連載
» 2017年04月24日 05時00分 公開

PHPの変数と代入、リテラルとエスケープシーケンスWeb業界で働くためのPHP入門(3)(2/2 ページ)

[山口晴広, 齊藤新三(改訂)/山田祥寛(改訂監修),WINGSプロジェクト]
前のページへ 1|2       

文字列リテラル

 文字列リテラルには何種類かあり、今まで出てきたのはダブルクオート(")でくくる型式です。

$foo = "Hello, World!";

 他に、シングルクオート(')でくくる形式もあります。

$foo = 'Hello, World!';

ダブルクオートとシングルクオートの違い

 では、ダブルクオートとシングルクオートの違いは何でしょうか。答えは、ダブルクオートによる文字列リテラルでは、変数を「展開」できるのです。つまり、文字列中に変数を書くと、変数の値に置き換えられるのです。例えば、以下のような場合です。

<?php
$foo = "Hello";
print("$foo, World!");
リスト5 phplesson/chap03/variablesInString.php

 実行結果は以下の通りです。

Hello, World!

 これは、つまりは、$fooの部分が変数の値に置き換えられたことを意味します。このことを「変数が展開される」と表現します。

変数名を{ }でくくる

 ところで、文字列リテラル中の変数名もやはり同じように文字列です。となると、気付いた人もいるかもしれませんが「どこまでが変数名なのか?」という問題が出てきます。リスト6では、変数名に使えないカンマがありますので「$foo」が変数名だということがすぐに判別できますが、次のようなケースはどうでしょうか。

<?php
$foo = "Hello, ";
print("$fooWorld");
リスト6 phplesson/chap03/variablesInString2.php

 実行結果は以下の通りエラーとなります。

図3 リスト6の実行結果

 エラーメッセージは、「変数fooWorldが未定義」という内容です。つまり、リスト6の記述方法では、文字列リテラルは「$fooWorld」という変数を展開しようとしたことになります。

 そこで、「$foo」が変数であることをはっきりさせるために、次のように変数名を{ }でくくります。

<?php
$foo = "Hello, ";
print("${foo}World");
リスト7 phplesson/chap03/variablesInString3.php

 実行結果は以下の通りです。

Hello, World!

 無事、$fooが展開されました。

エスケープシーケンス

 気付いた人もいるかもしれませんが、「文字列リテラル中にクオートを記述したらどうなるのだろうか?」という問題があります。次に、そこを扱いましょう。

ダブルクオートのときのエスケープシーケンス

 まず、ダブルクオートで定義した文字列リテラル中にダブルクオートを入れる場合を考えます。例えば、Worldを強調の意味で、下記のように文字列を定義したい場合です。

Hello, "World"!

 これをそのままダブルクオートで囲んだ場合、つまり、下記のようにした場合、Wの前のダブルクオートが文字列の終わりと見なされてしまいます。

$foo = "Hello, "World"!"

 つまり、「Hello, W」で1つの文字列リテラル、同様に、「!」で1つの文字列リテラルと見なされてしまい、間の「World」は処理対象コードと見なされてしまいます。

 そこで、World前後の「"」は文字列の始端、終端を意味する記号ではなく、文字列の一部であることが分かる記述にする必要があります。このことを、「エスケープする」といいます。

 また、その表記を「エスケープシーケンス」といい、その文字の前にバックスラッシュを記述します。つまり、「半角\"」と表記します。

 なお、Windowsの場合は半角¥記号になります。これは、Windowsがバックスラッシュと半角¥記号を識別していないからです。

 実際に以下のソースを実行してみましょう。

<?php
$foo = "Hello, \"World\"!";
print($foo);
リスト8 phplesson/chap03/escape.php

 無事「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」による「タブ」です。

 その他のエスケープシーケンスの一覧はレファレンスマニュアルを参照してください。

注意! 「ヒアドキュメントと終端ID」

 文字列リテラルは3種類あり、本編中で紹介しなかったものは「ヒアドキュメント」と呼ばれるものです。ヒアドキュメントは複数行の文字列をスマートに表現します。

<?php
$foo = <<<EOT
line1
line2
line3
EOT;
print($foo);
リスト9 phplesson/chap03/heredoc.php

 この場合は、下記のように表示されます。

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プロジェクト)。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。