新しい PHP プログラマにとって、PHP バッファはほぼ透明です。彼らの頭の中では、echo print_r 関数を使用すると、データが「シュッ」という音とともにブラウザに飛んで表示されることになります。私はいつもそうシンプルに考えてきました。 実際、テクノロジーの世界では、物事は常に単純さから複雑さへと進歩してきました。おそらく、テクノロジー開発者も最初はあなたや私と同じように単純でしたが、残酷な現実に直面して、改善するために戦略を調整する必要がありました。最後に、彼らは機械をより効率的にするためのアイデアを考えました。
バッファ、つまりバッファについて言えば、定義を比較するだけでは意味がありません。キャッシュは、データを迅速に検索して利用し、CPU 消費量を節約する方法の問題を解決します。一方、バッファリングは、高速 CPU と低速 I/O デバイス間の不一致の問題を解決します。
この記事のもう一人の主役であるob関数についてお話します。ob関数はoutput_bufferingの略です。 ob 関数は PHP 拡張関数であるため、ob 関数の主な操作は PHP バッファーです。 この記事の 2 人の主人公について簡単に説明した後、最初のトピックに戻る必要があります。echo print_r 関数によって出力されたデータはどのようにしてブラウザに到達し、ユーザーに表示されるのでしょうか。実際の処理は次のようになります:
Echo, print_r=>php Output_buffering=>webServerbuffer=>browserbuffer=>browser display
echo, print_r からそれがはっきりわかります。情報をクライアントに送信するための 2 つのバッファーと、クライアント側の 1 つのブラウザー バッファーを経由します。この記事の主な説明は php の出力バッファリングです。
ob 関数が使用されていない場合のバッファの使用法コードでは ob 関数がまったく使用されていないことがよくありますが、バッファは使用されますか?これはphpの設定によって異なります。バッファはphp.iniのoutput_buffering変数を通じて制御されます。デフォルト値はオフですが、バッファを開くにはオンに設定できます。バッファーを呼び出した後は、プログラム内で ob 関数が使用されていない場合でも、コードは実際にバッファーを使用します。さらに、php.ini の Output_buffering の設定に関係なく、cli モードの php はデフォルトで常にオフになります。
なぜ緩衝地帯なのか?簡単に言うと、高速CPUが自分のデータを早く処理して、それを回線を通してユーザーに渡したいのですが、回線が狭すぎて一度に送信できません。バッファーが導入されている場合、CPU は生成されたデータをバッファーにすぐに配置し、涼しい場所に保管できます。バッファは
コマンドに従ってタイムリーにデータを出力します。これにより、高速 CPU と低速 I/O デバイスの間の矛盾が効果的に解決されます。 バッファ内のデータはいつ出力されますか? 1. バッファがいっぱいの場合、バッファには容量があり、制限に達するとコンテンツが自動的に出力されます。 2. スクリプトの実行が完了します。多くの小さなプログラムはそれほど多くのコンテンツを出力しません。これは当然のことですが、バッファがいっぱいになるまで待つことはできません。
ob関数使用時のバッファ使用量
ob_start()
出力バッファをオンにします。この関数は、最も頻繁に呼び出される関数の 1 つです。 Output_buffering が on または x k に設定されている場合、この関数は出力バッファーを開くのではなく、出力バッファーを大きなサイズに拡張します。もちろん、output_buffering が off に設定されている条件では、ob_start がバッファをオープンする役割を果たします。 ob_start() は、オプションのパラメータである Output_callback 関数を渡すこともできます。これについては、公式 PHP マニュアルで詳しく説明されています。
ob_get_contents()
出力バッファの内容を取得するだけで、クリアしません。
ob_end_clean() と ob_clean()これら 2 つの関数の違いは、文字通り見ることができます。前者はバッファの内容をクリアして閉じますが、後者はクリア作業のみを行います。これら 2 つの関数を使用した後は、echo や print_r などの以前の関数はコンテンツを出力しなくなることに注意してください。
作者は一度、ob_get_contents() の内容を print_r で出力しようとした後、その後のバッファ上での操作に影響を与えないように ob_clean() を呼び出してバッファをクリアしようとしましたが、繰り返し失敗しました。よく考えてみると、print_rの内容が再度バッファに書き込まれ、後からob_clean()の操作が行われるため、当然出力はありません。 ob_clean 操作の前に ob_flush() 関数を呼び出すと、望ましい効果が得られます。
ob_flush()とflush()ob_flush()はバッファの内容を送信し、その内容を破棄します。したがって、この関数の前に ob_get_contents() を使用してバッファの内容を取得するのが最善です。 flash() はサーバー側のバッファをフラッシュしてクライアントに送信します。したがって、プロセスの観点からは、最初に ob_flush() を呼び出し、次にフラッシュ関数を呼び出す必要があります。
さらに、Apache バッファ flash() の動作原理を説明しましょう。Apache モジュールの sapi の下で、flush は、sapi_module() のフラッシュ メンバー関数ポインタを呼び出すことで、Apache の api::ap_rflush を間接的に使用して、Apache の出力バッファをリフレッシュします。もちろん、mod_gzip などの他の Apache モジュールはこのアクションの結果を変更し、出力バッファ自体を実行する可能性があります。これにより、flush() 関数によって生成された結果がクライアント ブラウザにすぐに送信されなくなります。
ob_get_clean()
ob_get_contents() と ob_clean() にすでに習熟している場合、この関数は非常に簡単です。それは最初の 2 つを組み合わせたものだからです。主に現在のバッファの内容を取得し、現在の出力バッファを削除します。
ob 関数は他にもたくさんありますが、そのほとんどは比較的使いやすく、理解しやすいものです。詳細な説明があるphpマニュアルを参照してください。この記事では、筆者が最初はよく理解できなかった機能をいくつか挙げています。もちろん、将来的には新たな問題が発生するかもしれません。