文字列リテラルには何種類かあり、今まで出てきたのはダブルクオート(")でくくる型式です。
$foo = "Hello, World!";
他に、シングルクオート(')でくくる形式もあります。
$foo = 'Hello, World!';
では、ダブルクオートとシングルクオートの違いは何でしょうか。答えは、ダブルクオートによる文字列リテラルでは、変数を「展開」できるのです。つまり、文字列中に変数を書くと、変数の値に置き換えられるのです。例えば、以下のような場合です。
<?php $foo = "Hello"; print("$foo, World!");
実行結果は以下の通りです。
Hello, World!
これは、つまりは、$fooの部分が変数の値に置き換えられたことを意味します。このことを「変数が展開される」と表現します。
ところで、文字列リテラル中の変数名もやはり同じように文字列です。となると、気付いた人もいるかもしれませんが「どこまでが変数名なのか?」という問題が出てきます。リスト6では、変数名に使えないカンマがありますので「$foo」が変数名だということがすぐに判別できますが、次のようなケースはどうでしょうか。
<?php $foo = "Hello, "; print("$fooWorld");
実行結果は以下の通りエラーとなります。
エラーメッセージは、「変数fooWorldが未定義」という内容です。つまり、リスト6の記述方法では、文字列リテラルは「$fooWorld」という変数を展開しようとしたことになります。
そこで、「$foo」が変数であることをはっきりさせるために、次のように変数名を{ }でくくります。
<?php $foo = "Hello, "; print("${foo}World");
実行結果は以下の通りです。
Hello, World!
無事、$fooが展開されました。
気付いた人もいるかもしれませんが、「文字列リテラル中にクオートを記述したらどうなるのだろうか?」という問題があります。次に、そこを扱いましょう。
まず、ダブルクオートで定義した文字列リテラル中にダブルクオートを入れる場合を考えます。例えば、Worldを強調の意味で、下記のように文字列を定義したい場合です。
Hello, "World"!
これをそのままダブルクオートで囲んだ場合、つまり、下記のようにした場合、Wの前のダブルクオートが文字列の終わりと見なされてしまいます。
$foo = "Hello, "World"!"
つまり、「Hello, W」で1つの文字列リテラル、同様に、「!」で1つの文字列リテラルと見なされてしまい、間の「World」は処理対象コードと見なされてしまいます。
そこで、World前後の「"」は文字列の始端、終端を意味する記号ではなく、文字列の一部であることが分かる記述にする必要があります。このことを、「エスケープする」といいます。
また、その表記を「エスケープシーケンス」といい、その文字の前にバックスラッシュを記述します。つまり、「半角\"」と表記します。
なお、Windowsの場合は半角¥記号になります。これは、Windowsがバックスラッシュと半角¥記号を識別していないからです。
実際に以下のソースを実行してみましょう。
<?php $foo = "Hello, \"World\"!"; print($foo);
無事「Hello, "World"!」と表示されることが確認できたと思います。
では、シングルクオート中のダブルクオートはどうなるのでしょうか。例えば、下記のような例です。
$foo = 'Hello, "World"!';
これは、そのまま出力されます。同様に、ダブルクオート中のシングルクオートはそのまま出力されます。例えば、下記のような場合です。
$foo = "Don't believe a word";
しかし、下記のようなコードは不可です。「Don」で1つの文字列リテラルと見なされてしまうからです。
$foo = 'Don't believe a word';
この場合は、先ほどと同じく、下記のようにします。
$foo = 'Don\'t believe a word';
さらに幾つかのエスケープシーケンスが使えますが、よく使うのは「半角\n」による「改行コード」(「LF」といわれるコード)や「半角\t」による「タブ」です。
その他のエスケープシーケンスの一覧はレファレンスマニュアルを参照してください。
文字列リテラルは3種類あり、本編中で紹介しなかったものは「ヒアドキュメント」と呼ばれるものです。ヒアドキュメントは複数行の文字列をスマートに表現します。
<?php $foo = <<<EOT line1 line2 line3 EOT; print($foo);
この場合は、下記のように表示されます。
line1 line2 line3
改行はHTMLでは空白扱いなので空白になっています。
「<<<」に続く文字列、上記の例では「EOT」という名前にしていますが、これは「終端ID」といい、任意の文字列を指定できます。終端IDが次に現れるまでの行が全て、文字列リテラルとなります。従って、そのヒアドキュメント内に存在しない行を終端IDとして採用しなければなりません。同じ終端IDを使って、同一ファイル内で複数のヒアドキュメントを使うことができますので、ヒアドキュメント内部と同じ文字列が使えない、ということです。
ヒアドキュメントは、ダブルクオートによるリテラルと全く同じ扱いです。「変数の展開」が行えますし、エスケープシーケンスが使えます。シングルクオートと同じ動作にしたい場合は、終端IDをシングルクオートでくくります。例えば、以下のようにします(厳密には、終端IDをシングルクオートでくくったものはヒアドキュメントではなく、「Nowdoc」といいます)。
$foo = <<<'EOT' line1 line2 line3 EOT;
終端IDを明示的にダブルクオートでくくると、やはりダブルクオートと同じ動作になります。
ちなみに、ヒアドキュメントを使わずとも複数行の文字列を格納することは可能です。例えば、以下のような例です。
$foo = "line1 line2 line3";
ただ、ヒアドキュメントの方が分かりやすいのは一目瞭然ですね。
数値リテラルは、数字を使ってそのまま指定するだけです。マイナスや小数点(ピリオド)を使うこともできます。
$minus = -10; $pi = 3.14;
ところで、次のように数字をクオートでくくった場合はどうなるでしょうか。
$foo = "123";
これはあくまでも文字列リテラルであり、数値ではありません。このような文字列と数値という違いは、「型」(または「タイプ」)の違いといいます。数値型は加減乗除といった計算が可能ですが、文字列型はできません。
言語によっては型の取り扱いが厳密ですが、PHPではいい感じに緩く扱うことができます。このゆるさが落とし穴になることもあるのですが、それは今後の連載でおいおい明らかになっていくでしょう。
今の段階ではひとまず、リテラルや、変数に格納したデータには「型」がある、ということを覚えておきましょう。
今回は、ここまでです。変数については、まだまだ解説しなければならないことがたくさんありますが、次回は条件分岐について解説します。
【2014/3/20】初版公開(山口晴広,株式会社イメージズ・アンド・ワーズ)。
【2017/4/24】PHP 7.1含め2017年の情報に合うように対応(齊藤新三/山田祥寛(監修),WINGSプロジェクト)。
Copyright © ITmedia, Inc. All Rights Reserved.