PHPは二重引用符、ヒアドキュメントを用いた時に変数を文字列中に展開できます。
PHP: 文字列 – Manual#変数のパース
<?php // https://www.php.net/manual/ja/language.types.string.php#language.types.string.parsing から引用 $juice = "apple"; echo "He drank some $juice juice.".PHP_EOL; // 動作しません。"s" は、変数名として有効な文字ですが、実際の変数名は $juice です。 echo "He drank some juice made of $juices."; // 動作します。波括弧で囲むことで、どこまでが変数名かを明示しているからです。 echo "He drank some juice made of ${juice}s."; ?>
プロパティや配列中の一要素も同様に展開できます。しかし次の様な関数の実行は展開できません。
$juice = "apple"; // He drank some {str_repat(apple, 2)} juice. とされ、期待通りの動作をしません。 echo "He drank some {str_repeat($juice, 2)} juice.".PHP_EOL; // Notice: Undefined variable: appleapple と警告が現れます。 // He drank some juice. とされ、期待通りの動作をしません。 echo "He drank some ${str_repeat($juice, 2)} juice.".PHP_EOL;
結局のところ、この変数展開機能はどこまでも変数の展開でしかなく、関数に対応していないのです。この中で関数を使うためには関数を変数として扱う必要があります。これは次のコードで実現できます。
<?php function functionExpanded(){ return function ($f){ return $f; }; } $_fe = functionExpanded(); $juice = "apple"; // He drank some appleapple juice. echo "He drank some {$_fe(str_repeat($juice, 2))} juice.".PHP_EOL;
引数の値をそのまま返す無名関数(クロージャとも)を持つ変数を定義し、その変数を文字列中で使い、その変数の引数に関数の実行結果をいれます。すると関数の実行結果が変数の中身となり、変数の展開結果が関数の実行結果となります。これによって文字列中で関数の実行結果を展開できます。
無名関数を利用する方法を紹介しましたが、これが成り立つ仕組みは少々面倒で手放しに使うには疑義があります(フレームワークかPHPがグローバル変数として置いてくれるのが標準になれば好き勝手使えそうですが)。読みにくくなりますが次の様に sprintf 関数を用いる方がどの様に動作しているか分かりやすくなります。一長一短なので状況に応じて適切に使い分けたいものです。
// He drank some appleapple juice. echo sprintf('He drank some %1$s juice.'.PHP_EOL, str_repeat($juice, 2));