【PHP実践|実務向け】PHPのヒアドキュメント内で関数を呼び出すトリッキーなテクニックとその是非

導入

PHPのヒアドキュメント(<<基礎知識

PHPのヒアドキュメントは、二重引用符(”)で囲まれた文字列と同様の解釈が行われます。そのため、{$variable}のような単純な変数や、配列の参照、オブジェクトのプロパティなどは展開されますが、{$func()}のような関数呼び出しは文法的に許可されていません。この制限を回避するには、PHPの仕様の隙間を突くような工夫が必要になります。

実装/解決策

ヒアドキュメント内で関数を実行したい場合、以下の2つのアプローチが有名です。

1. オブジェクトのメソッドを経由する
PHPのヒアドキュメント内でオブジェクトのプロパティやメソッドの戻り値は展開可能です。これを利用し、エスケープ関数を持つクラスをインスタンス化して呼び出します。

2. 可変変数(可変関数)を利用する
PHPでは文字列変数に格納された関数名を使って呼び出す機能があります。ヒアドキュメント内でも、関数名を代入した変数を使うことで関数呼び出しを擬似的に実現できます。

サンプルプログラム

以下のコードは、上記2つの手法を実装した例です。

alert(‘xss’);“;

echo <<クラスメソッド経由: {$esc->h($data)}

EOD;

// 手法2: 可変関数を利用する
$h = ‘htmlspecialchars’;
echo <<可変関数利用: {$h($data, ENT_QUOTES, ‘UTF-8’)}

EOD;
?>

応用・注意点

これらの手法はコードをすっきりと見せる効果がありますが、実務においては注意が必要です。

まず、チーム開発において「可変関数」のようなトリッキーな書き方は、他のエンジニアにとって可読性を下げ、思わぬバグの原因となります。また、静的解析ツール(PHPStanやPsalmなど)が正しくコードを追跡できなくなる可能性もあり、保守性の観点からは推奨されません。

現場で最も「安全」かつ「保守的」な方法は、ヒアドキュメントに渡す前にあらかじめエスケープ処理済みの変数を配列等にまとめておくことです。あるいは、テンプレートエンジン(Twigなど)を導入すれば、{{ variable|escape }}のようにテンプレート内で安全に関数を適用できるため、根本的な解決策として検討することをお勧めします。本稿で紹介したテクニックは、小規模なスクリプトや緊急時のハックとして留めておくのが賢明です。

タイトルとURLをコピーしました