標準出力を横取る

PHPがテンプレートに特化した言語だなぁと思っていたのだけれども、PHPで大きな開発をやるということになると、テンプレート内にロジックを書かない方が良くなってくる。もともとテンプレート用の言語だったのに、テンプレートを外側に出さないといけなくなって、かつ、 PHPの書き方をするといろんなとこに影響を及ぼすらしいので、テンプレート実装独自の書き方になっているという妙な状態。

ま、それはともかく、phpTenjinのソースを読んでいたらob_startなる関数を使っていることに気づいた。
それから、extract関数。引数に与えた連想配列のキーと値を現在のスコープ内で変数にしてしまう関数。便利。

function render($src,$context){
  extract($context);
  ob_start();
  eval('?>'.$src);
  $output = ob_get_contents();
  ob_end_clean()
  return $output;
}

$src は file_get_contentsとか使って読みこんだPHPの関数。function の中ではその外側で定義された変数を参照することはできない。
代わりに、$contextで与えられた連想配列の中身をextractで変数に展開することで、$src内部で参照している変数は$contextに依存するという状況を作り出すことができる。

出力をバッファリングして、変数に保存する為にob_startを呼び、evalで$srcを実行する。'?>'が必要なのは、PHPのevalが特殊だから。
で、バッファリングした出力結果を$outputに保存。バッファをクリアして$outputを返す。