私は個人的に、出力バッファリングは比較的純粋な 4.0 の機能だと考えています。概念的には非常に単純ですが、出力バッファリングは非常に強力であり、開発者は高度で効率的なプログラムを開発しやすくなります。
この記事では、HTTP ヘッダー、出力バッファリングが HTTP ヘッダーの処理にどのように役立つかを紹介し、出力バッファリングの高度な使用法をいくつか紹介します。
HTTPヘッダー
HTTP プロトコルを使用して確立されたすべてのリクエストに対して、Web サーバーによって生成されるレスポンスは通常、ヘッダーと本文の 2 つの部分で構成されます。たとえば、Web サーバーのドキュメント ルート ディレクトリに example.txt という小さなテキスト ファイルがあり、そのファイルに Hello, world! というテキストが含まれている場合、このファイルに対する HTTP リクエストの応答は次のようになります。
このHTTPヘッダーの情報はPHPスクリプトから追加・変更することができます。たとえば、 header() 関数を使用できます:
ブラウザはサーバーから返された HTTP ヘッダーを読み取り、foo という名前の Cookie (この場合はセッション Cookie) が送信されたこと、その値が bar であることを認識します。
出力バッファリングテクノロジーを使用する理由
出力バッファリング技術の必要性は、PHP/FI 2.0 の時点で明らかでした。このバージョンの PHP を使用したことがある場合は、「おっと、ヘッダーの送信後に SetCookie が呼び出されました」というエラー メッセージが頻繁に表示され、原因は何だったのか頭を悩ませたことをまだ覚えているかもしれません。
PHP の最新バージョン (PHP 3.0 または PHP 4.0) を使用したことがある場合は、次のエラー メッセージをご存知でしょう: おっと、ヘッダーが送信された後に php_set_cookie が呼び出されました。あるいは、PHP の header() 関数を呼び出そうとすると、「ヘッダー情報を追加できません - ヘッダーはすでに送信されました」というメッセージが表示される場合があります。一般に、出力バッファリング テクノロジのユーザーはこれらの煩わしいエラー メッセージを回避しますが、開発者はこれを高度な目的に使用することもできます。
これらのエラーはいつ発生しましたか?これらのエラー メッセージは、HTTP ヘッダーの送信後にヘッダー情報を追加または変更しようとした場合、およびドキュメント本文とヘッダーの間に空白行がない場合に発生する可能性があります。これがどのように起こるかを理解するために、PHP が HTTP ヘッダー出力と本文出力をどのように処理するかを見てみましょう。
スクリプトの実行が開始されると、ヘッダー情報と本文情報を同時に送信できます。
ヘッダー情報 (header() または SetCookie() 関数から) はすぐには送信されず、リストに保存されます。
これにより、デフォルトのヘッダー (Content-Type ヘッダーなど) を含むヘッダー情報を変更できます。ただし、スクリプトがヘッダー以外の出力を送信すると (たとえば、ブロックまたは print() 呼び出しを使用して)、PHP は最初にすべてのヘッダーを送信し、次に空行を送信して HTTP ヘッダーを終了し、その後のみ続行する必要があります。本文データを送信します。これ以降、ヘッダー情報を追加または変更しようとする試みは許可されず、上記のエラー メッセージのいずれかが送信されます。
これは大きな問題を引き起こしませんが、入力を送信する前に HTTP ヘッダーを終了するだけで、スクリプト ロジックが複雑になる場合があります。出力バッファリング技術はこれらの問題を解決できます。
出力バッファリングの仕組み
出力バッファリングが有効になっている場合、スクリプトが出力を送信するときに PHP は HTTP ヘッダーを送信しません。代わりに、この出力を動的に増加するキャッシュにパイプ処理します (集中出力メカニズムを持つ PHP 4.0 でのみ使用可能)。ヘッダーは実際には送信されないため、ヘッダー行の変更、追加、または Cookie の設定を行うことができます。最も単純なケースでは、スクリプトが終了すると、PHP は自動的に HTTP ヘッダーをブラウザーに送信し、出力バッファーの内容を送信します。それは簡単です。
基本的な使い方
出力バッファリングの制御に役立つ次の 4 つの関数を使用できます。
ob_end_flush()
出力バッファを送信し、出力バッファリングメカニズムを無効にします。
ob_end_clean()
送信せずに出力バッファをクリアし、出力バッファリングを無効にします。
ob_get_contents()
現在の出力バッファを文字列に返します。スクリプトによって出力された出力を処理できます。
また、php.iniのoutput_bufferingディレクティブを有効にすることもできます。このディレクティブが有効な場合、各 PHP スクリプトは最初に ob_start() 関数を呼び出すことと同じになります。
例1
例2
この例は、文字列の長さを決定する非効率的な方法を示しています。 strlen() 関数を単に使用するのではなく、最初に出力バッファリング メカニズムを有効にし、文字列を出力してから、出力バッファの長さを決定します。最後に出力バッファをクリアし (送信ではなく)、出力バッファリング メカニズムを無効にします。
出力バッファリングに関連する次の設定は、PHP.INI で設定できます:
名前 デフォルト値 スコープ修正レコード
output_buffering "0" PHP_INI_PERDIR
output_handler NULL PHP_INI_PERDIR PHP 4.0.4 以降で使用可能
implicit_flush "0" PHP の PHP_INI_ALL
簡単に説明すると次のとおりです:
output_buffering boolean/integer
このオプションを On に設定すると、すべてのスクリプトで出力制御が使用されます。出力バッファの最大サイズを制限したい場合は、このオプションを指定された最大バイト数に設定します (たとえば、output_buffering=4096)。 PHP バージョン 4.3.5 以降、このオプションは PHP-CLI では常にオフになります。
output_handler string
このオプションは、スクリプトのすべての出力を関数にリダイレクトできます。たとえば、output_handler が mb_output_handler() に設定されている場合、文字のエンコーディングは指定されたエンコーディングに変更されます。設定された処理関数は出力バッファリングを自動的に処理します。
注: mb_output_handler() と ob_iconv_handler() を同時に使用することはできません。また、ob_gzhandler() と zlib.output_compression を同時に使用することもできません。
注: このコマンドは組み込み関数のみが使用できます。ユーザー定義関数の場合は、ob_start() を使用します。
implicit_flush boolean
のデフォルトは FALSE です。このオプションを TRUE に変更すると、PHP は情報の各チャンクが出力された後に出力レイヤーを自動的に更新します。これは、print()、echo() などの関数を使用するたびに、または HTML ブロックごとに PHP で flash() 関数を呼び出すことと同じです。
Web 環境で PHP を使用しない場合、このオプションをオンにすると、プログラム実行のパフォーマンスに重大な影響を及ぼします。通常は、デバッグ中にのみ使用することをお勧めします。 CLI SAPI の実行モードでは、このフラグのデフォルトは TRUE です。
「ob_implicit_flush()」を参照してください。
変更する PHP.INI の場所がシステムで使用されている場所でない限り、設定すると間違いなく便利です。たとえば、通常は C::\WINDOWS\PHP.INI です。 もちろん、設定することもできます。他の場所へ。さらに、コンソール プログラムはバッファリングされません。
さらに、プログラム内で出力バッファを制御することもできます。マニュアルの「CXIV. 出力制御 出力制御関数」の章を参照してください。主な機能は次のとおりです:
flush -- 出力バッファをリフレッシュします。
ob_clean -- 出力バッファをクリーン (消去) します
ob_end_clean -- 出力バッファをクリーン (消去) し、出力バッファリングをオフにします
ob_end_flush -- 出力バッファをフラッシュ (送信) し、出力バッファリングをオフにします
ob_flush -- フラッシュ (送信) ) 出力バッファー
ob_get_clean -- 現在のバッファーの内容を取得し、現在の出力バッファーを削除します
ob_get_contents -- 出力バッファーの内容を返します
ob_get_flu...残りのテキスト>>
影響なし。
これは、ページコンテンツの出力を制御するだけです。ページが開かれると、ページコンテンツは最初にバッファーに保存され、ページが閉じられると、ページコンテンツが直接表示されます。表示のためにブラウザに送信されます。
このオプションでは、4096 などの数値も使用できます。これは、バッファーの内容が 4096 バイトに達したとき (または実行が完了したとき) にコンテンツがブラウザーに送信されることを意味します。