概要
PHPで変数や関数が入り混じったビューを記述しているときにそれを関数に収めてまとめて結果を返したい時ってあると思います。
例えばこんな感じにある関数からHTMLを返し、それをいろいろ編集したり、処理を加えてから出力する場面です。
<?php
function getFamilyName()
{
return "<p>仲良し家族</p>";
}
function getHtml()
{
$str = '';
$str .= '<div id="parent">';
$str .= getFamilyName();
$str .= '<div id="child-1">たいち</div>';
$str .= '<div id="child-2">たけし</div>';
$str .= '<div id="child-3">たけよし</div>';
$str .= '<div id="child-4">たけお</div>';
$str .= '</div>';
return $str;
}
$html = getHtml();
//何か処理した後
//何か処理した後
//何か処理した後
echo $html;
この中ではもちろんechoとかPHPタグで区切ってしまった時点で関数の実行時に出力されてしまうので、その方法はとれません。
ヒアドキュメントを使用した場合、下記のようになりますが、エディタによって整形が行えなかったりします。
また、中で関数が使用できないので、最初に変数に格納するといった処理が必要となってしまいますね。
<?php
function getFamilyName()
{
return "<p>仲良し家族</p>";
}
function getHtml()
{
$familyName = getFamilyName();
$str = <<<EOF
<div id="parent">
{$familyName}
<div id="child-1">たいち</div>
<div id="child-2">たけし</div>
<div id="child-3">たけよし</div>
<div id="child-4">たけお</div>
</div>
EOF;
return $str;
}
$html = getHtml();
echo $html;
こんなときは標準出力のバッファリングを扱うことによって綺麗にかつスマートにできます。
実際の手法
ob_start、ob_get_contentsという関数を使っていきます。
出力をバッファリングしてくれる関数です。
PHPのecho、print、PHPタグで囲われていない箇所は、標準出力といい、ブラウザであれば画面(ソース)に、ターミナルであればターミナル上に出力されます。
その出力内容を出力せず、一時的に蓄えるようにするのがob_startです。
実際に上のコードを書き直してみましょう。
<?php
function getFamilyName()
{
return "<p>仲良し家族</p>";
}
function getHtml()
{
ob_start(); // バッファリング開始
?>
<div id="parent">
<?php echo getFamilyName(); ?>
<div id="child-1">たいち</div>
<div id="child-2">たけし</div>
<div id="child-3">たけよし</div>
<div id="child-4">たけお</div>
</div>
<?php
$str = ob_get_contents(); // バッファリング取得
ob_end_clean(); // バッファリング終了
return $str;
}
$html = getHtml();
//何か処理した後
//何か処理した後
//何か処理した後
echo $html;
ob_startでまずバッファリングを開始します。ここから出力は一時的に蓄えられます。
ob_get_contentsで実行した時点の蓄えた出力内容を取得することができるので変数に格納することができます。
ob_end_cleanでバッファリングを終了、蓄えた出力内容を破棄します。
これによって、整形ツールなどでビュー部分をきれいに保てたり、値を返す関数をechoで出力しているものを、別に出力専用の関数がある場合そちらに書き直すこともできます。
実活用例
例えば、WordPressのショートコードで使用するための関数では、出力をその関数内で行うのではなく、出力したい結果を返す形が正しい形です。
他にも、テンプレートエンジンのようなものでも活用できるのではないでしょうか。
下記はWordPressのショートコードの例です。
add_shortcode('test', 'testFunc');
function testFunc()
{
ob_start();
?>
<div class="detail">
<div class="name"><?php the_title(); ?></div>
<div class="date"><?php the_date(); ?></div>
</div>
<?php
$str = ob_get_contents();
ob_end_clean();
return $str;
}
これでWordPressの記事本文で[test]という記述があれば、その記述の箇所に正しく出力してくれます。
参考