ユーザーレベルの出力バッファ

目次

ユーザレベルの出力バッファは、 PHP コードから開始、操作、終了することができます。 バッファは、出力バッファと関連する出力ハンドラ関数を含みます。

出力バッファをオンにする

出力バッファリングは、php.ini 設定 output_bufferingoutput_handler を設定するか、ob_start 関数を使うことでオンにできます。 これらは両方、出力バッファを生成できますが、 ob_start の方がより柔軟です。 なぜなら、出力ハンドラをユーザー定義関数として受け入れますし、 (フラッシュ、クリーン、削除 のような) バッファに対する操作もできるからです。 ob_start で開始したバッファは、 それをコールした行からアクティブになりますが、 output_buffering を使って開始したバッファは、スクリプトの最初の行から、出力をバッファします。

PHP は組み込みの "URL-Rewriter" 出力ハンドラをバンドルしています。 このハンドラは、自分の出力バッファを開始します。 同時に実行できるのはふたつです(1つはユーザレベルのURL書き換えと、 透過的なセッションIDサポートのためのもの) 。 これらのバッファは、output_add_rewrite_var 関数をコールするか、php.ini 設定 session.use_trans_sid を有効にすることで開始できます。

バンドルされている zlib 拡張モジュールは、 独自の出力バッファを持っています。 この出力バッファは、php.ini 設定 zlib.output_compression を使うことで有効にできます。

注意: 一度に二つまでしか実行できないという意味で、 "URL-Rewriter" は特別です。 しかし、すべてのユーザレベルの出力バッファは、 カスタムの出力ハンドラ関数を指定して ob_start をコールすることで開始した既存のバッファと同じものを使います。 そのため、すべての機能はユーザランドのコードでエミュレートすることができます。

バッファの内容をフラッシュ/アクセス/削除する

フラッシュは、アクティブなバッファの内容を送信し、破棄します。 出力バッファは、出力のサイズがバッファのサイズを超えたときか、 スクリプトが終了するか、 ob_flush, ob_end_flush, ob_get_flush のいずれかがコールされたときにフラッシュされます。

警告

ob_end_flushob_get_flush をコールすると、アクティブなバッファがオフになります。

警告

バッファをフラッシュすると、 出力バッファの戻り値がフラッシュされますが、 この値はバッファの内容と異なる場合があります。 例えば、ob_gzhandler を使うと、出力が圧縮され、圧縮された出力がフラッシュされます。

アクティブなバッファの内容は ob_get_contents, ob_get_clean, ob_get_flush をコールすると取得できます。

バッファの中身の長さだけが必要な場合、 ob_get_lengthob_get_status を使えばバッファの中身の長さをバイト単位で取得できます。

警告

ob_get_cleanob_get_flush をコールすると、アクティブなバッファの中身を返した後、 そのバッファをオフにします。

アクティブなバッファの中身は、 ob_clean, ob_end_clean, ob_get_clean を使って削除できます。

警告

ob_end_cleanob_get_clean を使うと、アクティブなバッファがオフになります。

出力バッファをオフにする

ob_end_clean, ob_end_flush, ob_get_flush, ob_get_clean をコールすると、出力バッファをオフにできます。

警告

PHP_OUTPUT_HANDLER_REMOVABLE を指定せずに起動した出力バッファはオフにできず、 E_NOTICE が発生します。

スクリプトの終了時、または exit がコールされるまでに閉じられていないすべての出力バッファは、 PHP のシャットダウン処理によってフラッシュされ、オフになります。 バッファは、起動した順序と逆の順序でフラッシュされ、オフになります。 最後にバッファリングが開始されたものが最初になり、 最初にバッファリングが開始されたものが最後にフラッシュされ、オフになります。

警告

バッファの内容をフラッシュしたくない場合は、 カスタムの出力ハンドラを使い、シャットダウン中のフラッシュを防ぐべきです。

出力ハンドラでスローされる例外

捕捉されない例外が出力ハンドラでスローされた場合、 プログラムは終了し、"Uncaught Exception" エラーメッセージがフラッシュされた後に、 シャットダウン処理によってハンドラが呼び出されます。

ob_flush, ob_end_flush, ob_get_flush が呼び出したハンドラが、捕捉されない例外をスローした場合、 エラーメッセージがフラッシュされる前にバッファの内容がフラッシュされます。

シャットダウン処理中に出力ハンドラが捕捉されない例外をスローした場合、 ハンドラは終了し、バッファの内容もエラーメッセージもフラッシュされません。

注意: ハンドラが例外をスローした場合、 PHP_OUTPUT_HANDLER_DISABLED フラグが設定されます。

出力ハンドラで発生したエラー

出力ハンドラで致命的でないエラーが発生した場合、 プログラムの実行は継続されます。

ob_flush, ob_end_flush, ob_get_flush が呼び出したハンドラで致命的でないエラーが発生した場合、 ハンドラの戻り値に応じて、バッファは一定のデータをフラッシュします。 ハンドラが false を返す場合、 バッファの中身とエラーメッセージがフラッシュされます。 それ以外の値をハンドラが返す場合、 ハンドラの戻り値はフラッシュされますが、エラーメッセージはフラッシュされません。

注意: ハンドラが false を返す場合、 PHP_OUTPUT_HANDLER_DISABLED フラグが設定されます。

出力ハンドラ中で致命的なエラーが発生した場合、 プログラムは終了し、 エラーメッセージがフラッシュされた後に、 シャットダウン処理によってハンドラが呼び出されます。

ob_flush, ob_end_flush, ob_get_flush が呼び出したハンドラで、致命的なエラーが発生した場合、 エラーメッセージがフラッシュされる前にバッファの内容がフラッシュされます。

シャットダウン処理中に出力ハンドラで致命的なエラーが発生した場合、 プログラムは終了し、バッファの内容もエラーメッセージもフラッシュされません。

出力ハンドラで行われた出力

特定の状況下では、 ハンドラ内で生成された出力はバッファの内容と共にフラッシュされます。 この出力はバッファに追加されず、 ob_get_flush が返す文字列の一部にもなりません。

フラッシュの操作中 (ob_flush, ob_end_flush, ob_get_flush のコール中、またはシャットダウン処理中)に、 ハンドラが false を返した場合、 バッファの内容がフラッシュされ、その後に出力が行われます。 シャットダウン処理中にハンドラが呼び出されなかった場合、 ハンドラが例外をスローするか、exit が呼び出されると、 同じ動作になります。

注意: ハンドラが false を返した場合、 PHP_OUTPUT_HANDLER_DISABLED が設定されます。

出力ハンドラのステータスフラグ

バッファが持つ flags ビットマスクの 出力ハンドラのステータスフラグ は、 出力ハンドラが起動されるたびに設定され、 ob_get_status が返す flags の一部になります。 ハンドラが正常に実行され、false を返さなかった場合、 PHP_OUTPUT_HANDLER_STARTEDPHP_OUTPUT_HANDLER_PROCESSED が設定されます。 ハンドラが false を返すか、実行中に例外がスローされた場合は、 PHP_OUTPUT_HANDLER_STARTEDPHP_OUTPUT_HANDLER_DISABLED が設定されます。

注意: ハンドラの PHP_OUTPUT_HANDLER_DISABLED が設定されている場合、 ob_end_clean, ob_end_flush, ob_get_clean, ob_get_flush ob_clean, ob_flush 経由でハンドラは呼び出されません。 PHP のシャットダウン処理中でも同様です。 PHP 8.4.0 より前のバージョンでは、 ob_cleanob_flush をコールしてもこのフラグはなんの意味もありませんでした。