ヒアドキュメントは複数行の文字列です。<<<EOTで始め、続く行にテキストを書き、EOT;だけの行で終えます。中の変数は、ダブルクォートの文字列と同じように置き換えられます。
識別子(ここではEOT)は、英字かアンダースコアのあとに英字、数字、アンダースコアが続く名前です。テキストの内容を表す名前がよく選ばれます:HTML、SQL、TEXT。PhpStormをはじめ一部のエディターは、名前がHTMLやSQLのとき本文をその言語としてハイライトします。
ヒアドキュメントでHTMLテンプレートを作る
値を含むHTMLのかたまりを書くには、ヒアドキュメントがいちばんわかりやすい方法です。マークアップの形がそのまま保たれ、何もエスケープしなくてすむからです。出力はHTMLなので、エディターはPageタブに表示します。
このブロックには2つのポイントがあります。配列の要素は{$product['name']}のように波括弧で囲み、価格の前の文字どおりのドル記号は\$とエスケープしています。名前を変えたりタグを足したりして、もう一度実行してみてください。
ユーザーから来た値は、HTMLに入れる前にエスケープする必要があります。理由と方法はhtmlspecialcharsを参照してください。
Nowdoc:展開しないテキスト
Nowdocは識別子をシングルクォートで囲みます:<<<'EOT'。中では何も置き換えられないので、ドル記号とバックスラッシュは書いたとおりに残ります。コードのサンプル、正規表現、$を含むテキストに使います。
終端識別子をインデントする
PHP 7.3以降は終端識別子をインデントでき、そのインデントが本文の各行から取り除かれます。そのため、関数やifの中のヒアドキュメントも、空白を文字列に含めずにコードのインデントに合わせられます。
json_encodeの行は、結果を1文字ずつ見えるようにしています。終端のTEXT;が8文字インデントされているので、各行から8つの空白が取り除かれました。
本文の行が終端識別子よりインデントが浅いと、構文エラーになります。
$html = <<<HTML
<p>Hello</p>
HTML;
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 4) in /home/index.php on line 3
ヒアドキュメントの中の配列、オブジェクト、メソッド呼び出し
ヒアドキュメントはダブルクォートと同じルールに従います。単純な変数はそのままで動きます。引用符付きの配列キー、ネストした配列、プロパティ、メソッド呼び出しには波括弧を使います。
関数の引数にヒアドキュメントを渡す
PHP 7.3以降は、終端識別子の同じ行にさらにコードを続けられるので、ヒアドキュメントを関数に直接渡したり、配列に入れたりできます。sprintfと組み合わせれば、プレースホルダーをあとで埋めるテンプレートになります。
よくあるミス:セミコロンがない、識別子のあとに余計な文字がある
終端識別子は開始時とまったく同じ(大文字小文字も同じ)に書く必要があり、その行で識別子に続くものはPHPとして意味が通らなければなりません。EOT;は文を終え、EOT,は引数リストを続けます。識別子の直後に英字や数字があると(EOTX;)識別子として認識されないので、文字列がファイルの最後まで続き、PHPはsyntax error, unexpected end of fileを報告します。逆の落とし穴は、EOT is the markerのように識別子のあとに空白や記号が続く行で本文の行が始まる場合です。そこで文字列が早く終わってしまい、その行の残りがPHPとして読まれます(syntax error, unexpected identifier "is")。マークアップならHTML、クエリならSQLのように、テキストの行頭に決して現れない識別子を選びましょう。
よくある質問
PHPのヒアドキュメントとは何ですか?
引用符を使わずに複数行の文字列を書く方法です。<<<EOTと改行で始め、テキストを書き、最後にEOT;だけの行で終えます。中の変数はダブルクォートの文字列とまったく同じように置き換えられ、"と'は自由に使えます。
ヒアドキュメントとNowdocの違いは何ですか?
ヒアドキュメント(<<<EOT)は、ダブルクォートの文字列と同じく変数とエスケープシーケンスを置き換えます。Nowdoc(<<<'EOT'、識別子をシングルクォートで囲む)はどちらも行わず、シングルクォートの文字列と同じく$とバックスラッシュをすべて書いたとおりに保ちます。
ヒアドキュメントの終端識別子はインデントできますか?
PHP 7.3以降はできます。終端識別子のインデントが本文の各行から取り除かれるので、コードに合わせてヒアドキュメントをインデントできます。本文のすべての行は終端識別子と同じかそれ以上にインデントされている必要があり、そうでなければPHPは構文エラーで止まります。
ヒアドキュメントの中で関数を呼び出すには?
ヒアドキュメントが展開するのは、変数、配列の要素、プロパティ、メソッド呼び出しだけです。先に関数を呼んで結果を変数に入れるか、関数名やクロージャを変数に入れて波括弧の中で呼び出します:$e = 'htmlspecialchars';としてから{$e($text)}。