PHPでは、出力バッファー(出力バッファー)は、出力コンテンツのキャッシュに使用されるキャッシュメカニズムです。出力バッファーを有効にすることにより、HTMLコンテンツまたはその他の情報の出力を開始するタイミングを制御でき、すぐにブラウザへの送信を避けます。これは、出力を遅延、変更、または他の出力ストリームと対話する必要があるシナリオを処理するのに役立ちます。
OB_Start()で出力バッファーを起動した後、PHPはすべての出力コンテンツをメモリに保存し、すぐにブラウザに送信されません。必要に応じて、開発者はob_get_contents()を使用してキャッシュされたコンテンツを取得したり、 ob_end_flush()を介してキャッシュされたコンテンツをブラウザに送信したりできます。
いくつかの複雑なアプリケーションシナリオでは、1つのバッファー内で別のバッファを起動する必要がある場合があります。たとえば、ネストされた出力バッファーを使用すると、複数のテンプレートを操作したり、動的コンテンツを生成したり、カスタム出力を生成したりすると、柔軟性が向上します。いくつかの一般的なネストされたバッファ使用シナリオは次のとおりです。
テンプレートエンジン:テンプレートエンジンは通常、バッファーでテンプレート出力をキャプチャし、これらのコンテンツを外部でさらに処理します。
コンテンツの変更:特定の出力コンテンツをキャプチャして変更または分析する必要がある場合がありますが、コンテンツの一部を最初にキャッシュする必要があります。
出力ストリームのリダイレクト:ネストされたバッファーを使用すると、メインの出力ストリームに影響を与えることなく、特定のコンテンツをファイルまたはデータベースにリダイレクトできます。
複数のネストされた出力バッファーを管理することは、単一のバッファーを管理するほど簡単ではありません。デフォルトでは、PHPは最初に最後のスタートバッファーエンディングをサポートするため、ネストされたバッファーの管理は特に重要です。これらのバッファーを効率的に管理するには、次の方法をとることができます。
PHP 5.4の後、 OB_START()は命名バッファーをサポートします。各出力バッファーの異なる名前を指定することにより、複数のネストされたバッファー間の混乱を回避できます。名前付きバッファーを使用する場合、バッファを終了するたびに、他のバッファーではなく、現在のバッファーにのみ影響します。
<span><span><span class="hljs-title function_ invoke__">ob_start</span></span><span>(</span><span><span class="hljs-string">"output_handler"</span></span><span>, </span><span><span class="hljs-number">4096</span></span><span>, PHP_OUTPUT_HANDLER_CLEANABLE);
</span><span><span class="hljs-title function_ invoke__">ob_start</span></span><span>(</span><span><span class="hljs-string">"another_handler"</span></span><span>, </span><span><span class="hljs-number">4096</span></span><span>, PHP_OUTPUT_HANDLER_CLEANABLE);
</span></span>
上記の例では、 output_handlerと別の_handlerは2つの独立した出力バッファーであり、それらの出力は互いに干渉しません。
外部バッファに影響を与えることなく、特定のネストされたバッファーの最後にその内容を取得する必要がある場合があります。これは、バッファのレベルを制御することで実現できます。
<span><span><span class="hljs-title function_ invoke__">ob_start</span></span><span>(); </span><span><span class="hljs-comment">// 最初のバッファー</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"これは外部バッファのコンテンツです\n"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">ob_start</span></span><span>(); </span><span><span class="hljs-comment">// 2番目のネストされたバッファー</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"これは内部バッファのコンテンツです\n"</span></span><span>;
</span><span><span class="hljs-variable">$nestedContent</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ob_get_contents</span></span><span>();
</span><span><span class="hljs-title function_ invoke__">ob_end_clean</span></span><span>(); </span><span><span class="hljs-comment">// 内側のバッファーを終了します</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"内部バッファーの内容:<span class="hljs-subst">$nestedContent</span></span></span><span>\n";
</span><span><span class="hljs-title function_ invoke__">ob_end_flush</span></span><span>(); </span><span><span class="hljs-comment">// 外側のバッファーを終了します</span></span><span>
</span></span>
内部バッファーの内容をOB_GET_CONTENTS()から取得し、内容を出力せずにOB_END_CLEAN()で内部バッファーを終了します。これらは、外部バッファで使用できます。
開発者は、バッファーがクリアされる前にバッファーのコンテンツを変更したい場合があります。この時点で、コールバック関数を設定して出力コンテンツを処理できます。 ob_start()は、パラメーターとしてコールバック関数を受信し、バッファコンテンツがリリースされたときに関数を自動的に実行できます。
<span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">modify_output</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$buffer</span></span></span><span>) {
</span><span><span class="hljs-comment">// 出力コンテンツを変更します</span></span><span>
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">str_replace</span></span><span>(</span><span><span class="hljs-string">"PHP"</span></span><span>, </span><span><span class="hljs-string">"PHP 7"</span></span><span>, </span><span><span class="hljs-variable">$buffer</span></span><span>);
}
</span><span><span class="hljs-title function_ invoke__">ob_start</span></span><span>(</span><span><span class="hljs-string">"modify_output"</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Welcome to PHP!"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">ob_end_flush</span></span><span>(); </span><span><span class="hljs-comment">// 最初に実行されます modify_output,次に、変更されたコンテンツを出力します</span></span><span>
</span></span>
これを行うと、バッファー内のコンテンツを手動で操作せずにバッファコンテンツを出力するたびにバッファコンテンツが変更されることが保証されます。
複数のネストされたバッファーを管理するとき、一般的な質問は、バッファをいつ終了するかを合理的に選択する方法です。通常、バッファーの終了のタイミングは、出力の階層に関連する必要があります。 OB_END_FLUSH()またはOB_END_CLEAN()を使用して、最も内側のバッファコンテンツと出力を終了したり、後続の使用のためにそれらを維持したりできます。
ob_end_flush() :現在のバッファーを終了し、コンテンツをブラウザに出力します。
OB_END_CLEAN() :現在のバッファーを終了しますが、何も出力せず、バッファ内のデータを直接破棄します。
これら2つを選択することで、出力コンテンツをより柔軟に制御できるようになります。
PHPアプリケーションをデバッグすると、出力バッファー管理が混乱を招く可能性があります。特に、バッファが深くネストされている場合、デバッグ情報の出力の順序は期待と矛盾する可能性があります。ネストされた出力バッファーをより適切に管理するには、 ob_get_level()を使用して、現在のバッファーの深さを確認し、デバッグ中に現在アクティブになっているバッファーを表示できます。
<span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"現在のバッファーの深さ: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">ob_get_level</span></span><span>();
</span></span>
これらのツールを通じて、複数のネストされたバッファーを効果的に追跡および管理できます。