「複数行の文字列を、見たままスッキリ記述する方法はないの?」
PHPでプログラミングをしていると、このような悩みに直面することが多いです。
特に、文字列の中に多くの変数や引用符が含まれる場合、コードはどんどん読みにくくなっていくでしょう。
この問題をエレガントに解決してくれるのが、PHPの「ヒアドキュメント」構文です。
この記事では、PHPのヒアドキュメントについて、基本的な書き方と厳格なルールから、変数・配列・オブジェクトの展開といった応用的な使い方、インデント、そしてよく似た「Nowdoc」との違いまで、豊富なサンプルコードと共に徹底的に解説します。
【本記事の信頼性】
- 執筆者は元エンジニア
- 大手プログラミングスクールのWebディレクター兼ライターを経験
- 自らも地元密着型のプログラミングスクールを運営
受講生から評判の良いプログラミングスクール
スクール |
特徴 |
受講料金 |
大手比較サイトで4年連続人気NO.1!受講生からの評判も非常に高く、Web系のエンジニアを目指すならRUNTEQ一択。 | 550,000円(給付金適用あり) | |
月単価80万円以上の現役エンジニア講師による指導!一度入会すればサポートは半永久的。 | 498,000円 | |
格安で質の高いWeb制作スキルを習得したい人におすすめ!業界最安級の料金でありながら、コミュニティやサポートが充実。 | 129,800円~ | |
完全無料でプログラミングが学べる貴重なスクール!最短1ヶ月で卒業可能。ゼロスク運営会社への就職もできる。 | 無料 | |
長期間に渡って学習し、希少人材を目指す人に最適なスクール!受講料は高いものの、高収入を得られる人材を目指せる。 | 96~132万円 |
そもそもPHPのヒアドキュメントとは何か?
ヒアドキュメントは、PHPで複数行にわたる文字列を扱うための構文(シンタックス)の一つです。
開始と終了の目印(識別子)を使い、その間に挟まれたテキストを、改行なども含めてすべて一つの文字列として定義できます。
ヒアドキュメントを使う最大のメリット:エスケープからの解放
ヒアドキュメントがなぜこれほど便利なのか。
その最大の理由は、文字列内でシングルクォーテーション('
)やダブルクォーテーション("
)を「エスケープ」する必要がなくなる点にあります。
例えば、HTMLコードを変数に代入する場面を考えてみましょう。
【通常の文字列の場合(エスケープが面倒)】
<?php
$userName = '山田';
$html = "<div class=\"user-profile\">\n"
. " <p>こんにちは、 \"{$userName}\" さん。</p>\n"
. "</div>\n";
このように、ダブルクォーテーションを文字列内で使うには、バックスラッシュ(\
)でエスケープする必要があり、非常に読みにくいです。
【ヒアドキュメントの場合(見たまま書ける)】
<?php
$userName = '山田';
$html = <<<HTML
<div class="user-profile">
<p>こんにちは、 "{$userName}" さん。</p>
</div>
HTML;
ヒアドキュメントを使えば、HTMLコードをそのままコピー&ペーストしたかのように、直感的に記述できます。
これにより、コードの可読性が劇的に向上するのです。
ヒアドキュメントの基本的な書き方と厳格なルール
ヒアドキュメントは非常に便利ですが、いくつかの厳密なルールが存在します。
これを一つでも破るとパースエラー(文法エラー)になるため、最初にしっかりとマスターしておきましょう。
-
開始識別子
<<<
の直後に、文字列の開始を示すための「識別子」を記述します。識別子には、英数字とアンダースコアが使用でき、先頭は数字以外である必要があります。慣習的にEOD
(End of Data),EOT
(End of Text),HTML
,SQL
などがよく使われます。開始識別子の行には、これ以外の文字を記述してはいけません。 -
終了識別子
文字列の最後に、開始識別子と全く同じ文字列を記述して、文字列の終わりを示します。 -
終了識別子のルール(最重要)
終了識別子は、必ず行の先頭から記述する必要があります。インデント(字下げ)やスペースが前にあると、エラーになります。また、終了識別子の直後には、セミコロン(;
)を置くか、すぐに改行しなければなりません。この行には、識別子とセミコロン以外の一切の文字を含めることができません。
【正しい書き方の例】
<?php
// 開始識別子 EOT
$text = <<<EOT
ここに複数行にわたる
自由なテキストを
記述することができます。
EOT; // 終了識別子 EOT。インデントはNG。
echo $text;
ヒアドキュメントにおける変数の展開
ヒアドキュメントのもう一つの強力な機能が「変数展開」です。
ダブルクォーテーションで囲んだ文字列と同じように、ヒアドキュメント内に書かれた変数は、その値に自動的に置き換えられます。
単純な変数を展開する方法
まずは、文字列や数値といった単純な変数を展開する基本的な方法です。
【ソースコード】
<?php
$name = '鈴木一郎';
$team = 'オリックス・バファローズ';
$playerInfo = <<<EOD
選手名: $name
所属チーム: $team
EOD;
echo $playerInfo;
【実行結果】
選手名: 鈴木一郎
所属チーム: オリックス・バファローズ
ヒアドキュメント内に記述された $name
と $team
が、それぞれ変数に格納された値に置き換えられて出力されています。
非常にシンプルで直感的に利用できることがわかります。
波括弧 {} を使った変数の明示(推奨)
変数の直後に他の文字が続く場合など、変数の境界が曖昧になりそうなケースでは、変数名を波括弧 {}
で囲むことが推奨されます。
これにより、どこまでが変数名なのかをPHPに明確に伝えることができます。
【ソースコード】
<?php
$animal = '猫';
// 波括弧がないと、$animalは までが変数名だと解釈されかねない
$text = <<<EOT
私は{$animal}派です。
EOT;
echo $text;
【実行結果】
私は猫派です。
この例では、{$animal}
と記述することで、変数が$animal
であることを明示しています。
もし波括弧がないと、PHPは$animal派
という名前の変数を探そうとしてしまい、意図通りに動作しません。
安全のため、ヒアドキュメント内で変数を展開する際は、常に波括弧で囲む癖をつけるとよいでしょう。
【応用編】配列・オブジェクト・関数を変数展開する方法
ヒアドキュメントでは、単純な変数だけでなく、配列の要素やオブジェクトのプロパティ、さらには関数の戻り値まで展開することが可能です。
配列の要素を展開する
配列の要素を展開する場合、波括弧{}
の使用が必須となります。
【ソースコード】
<?php
$user = [
'id' => 1,
'name' => '佐藤健',
'address' => [
'prefecture' => '東京都',
'city' => '千代田区'
]
];
$addressLabel = <<<HTML
<div class="address">
<p>ID: {$user['id']}</p>
<p>氏名: {$user['name']}</p>
<p>住所: {$user['address']['prefecture']}{$user['address']['city']}</p>
</div>
HTML;
echo $addressLabel;
【実行結果】
<div class="address">
<p>ID: 1</p>
<p>氏名: 佐藤健</p>
<p>住所: 東京都千代田区</p>
</div>
{$user['name']}
や{$user['address']['prefecture']}
のように、配列にアクセスする式全体を波括弧で囲むことで、正しく値を取り出すことができます。
オブジェクトのプロパティ・メソッドを展開する
オブジェクトのプロパティやメソッドの返り値も、同様に波括弧{}
で囲むことで展開できます。
【ソースコード】
<?php
class Product
{
public string $name = 'りんご';
private int $price = 150;
public function getPriceWithTax(): int
{
return (int)($this->price * 1.1);
}
}
$product = new Product();
$productDetail = <<<EOD
商品名: {$product->name}
税込価格: {$product->getPriceWithTax()} 円
EOD;
echo $productDetail;
【実行結果】
商品名: りんご
税込価格: 165 円
{$product->name}
でパブリックプロパティに、{$product->getPriceWithTax()}
でメソッドの戻り値にアクセスしています。
このように、複雑な式も波括弧で囲むことで、ヒアドキュメント内で直接評価し、その結果を埋め込むことが可能です。
変数が展開されない?Nowdocとの違いを理解しよう
「ヒアドキュメントと同じように書いたのに、変数が展開されず$name
のようにそのまま表示されてしまう・・・」
この現象が起きた場合、あなたは「Nowdoc」構文を使用している可能性が非常に高いです。
Nowdocとは?
Nowdocは、ヒアドキュメントとほぼ同じ見た目の構文ですが、一切の変数展開を行わないという決定的な違いがあります。
その挙動は、PHPのシングルクォーテーション('
)で囲んだ文字列と全く同じです。
Nowdocは、開始識別子をシングルクォーテーションで囲んで<<<'EOT'
のように記述します。
【ソースコード(Nowdocの例)】
<?php
$framework = 'Laravel';
$codeSample = <<<'CODE'
$name = 'Taro';
echo "Hello, {$name}!";
// この $framework は展開されません。
CODE;
echo $codeSample;
【実行結果】
$name = 'Taro';
echo "Hello, {$name}!";
// この $framework は展開されません。
開始識別子を<<<'CODE'
とシングルクォーテーションで囲んだため、内部の$framework
変数は展開されず、文字列としてそのまま出力されています。
ヒアドキュメントとNowdocの使い分け
構文 | 開始識別子 | 変数展開 | 主な用途 |
---|---|---|---|
ヒアドキュメント | <<<ID |
される | 変数を含んだHTMLやSQL文の生成 |
Nowdoc | <<<'ID' |
されない | PHPコードのサンプルや、変数を展開したくない固定のテンプレート文書 |
この2つを明確に使い分けることが、意図しない挙動を防ぐ鍵となります。
【PHP7.3以降】インデント可能なFlexible Heredoc
従来のヒアドキュメントの最大の弱点は、「終了識別子をインデントできない」という点でした。
これにより、関数やメソッド内でヒアドキュメントを使うと、その部分だけインデントが崩れ、コードの見た目が悪くなっていました。
この問題を解決したのが、PHP7.3で導入されたFlexible Heredoc and Nowdoc構文です。
【ソースコード (Flexible Heredoc)】
<?php
class MyClass
{
public function getHtml(): string
{
$title = 'ようこそ';
// 終了識別子 `HTML` をインデントできる!
return <<<HTML
<div class="container">
<h1>{$title}</h1>
</div>
HTML;
}
}
この新しい構文では、終了識別子をインデントすることができます。
そして、終了識別子のインデント量が、ヒアドキュメント全体のインデントを取り除く基準となります。
上記の例では、終了識別子が8つのスペースでインデントされているため、ヒアドキュメント内の各行の先頭から8つのスペースが取り除かれて出力されます。
これにより、コードのインデントを崩すことなく、ヒアドキュメントを綺麗に記述できるようになりました。
まとめ
この記事では、PHPのヒアドキュメントについて、基本的な使い方から変数展開の応用テクニック、そしてNowdocとの違いや最新機能までを詳しく解説しました。
なお、PHPを体系的に学んだり、PHPのスキルを高めたりするためには、プログラミングスクールを利用するのも有効です。
細かな疑問がすぐに解決するだけでなく、現役エンジニアが「質の高いポートフォリオ」を作成するための手助けをしてくれたり、エンジニア就職・転職のコツを教えてくれたりするなど、様々なメリットがありますので、独学に疲れた方は検討してみてはいかがでしょうか。