php ob 関数と組み合わせてバッファリングの仕組みを理解する
始めたばかりの php プログラマーにとって、php バッファはほぼ透明です。彼らの頭の中では、echo print_r 関数を使用すると、データが「シュッ」という音とともにブラウザに飛んで表示されることになります。私はいつもそうシンプルに考えてきました。 実際、テクノロジーの世界では、物事は常に単純さから複雑さへと進歩してきました。おそらく、テクノロジー開発者も最初はあなたや私と同じように単純でしたが、残酷な現実に直面して、改善するために戦略を調整する必要がありました。最後に、彼らは機械をより効率的にするためのアイデアを考えました。
バッファリング、つまりバッファに関しては、単純に定義を比較するだけでは意味がありません。キャッシュは、データを迅速に検索して利用し、CPU 消費量を節約する方法の問題を解決します。一方、バッファリングは、高速 CPU と低速 I/O デバイス間の不一致の問題を解決します。
この記事のもう 1 つの主役である ob 関数について説明します。 ob は、output_buffering の略です。 ob関数はPHPの拡張関数であるため、ob関数は主にでPHPのバッファを操作します。
この記事の 2 人の主人公について簡単に説明した後、最初のトピックに戻る必要があります。echo print_r 関数によって出力されたデータはどのようにしてブラウザに到達し、ユーザーに表示されるのでしょうか。実際の処理は次のようになります。
echo, print_r=>
echo, print_r=>
echo 関数と print_r 関数からクライアントに情報を送信するまで、2 つのバッファーを経由し、クライアントもブラウザーのバッファーを経由することが明確にわかります。この記事の主な説明は php の出力バッファリングです。
ob 関数が使用されていない場合のバッファ使用量
多くの場合、コードでは ob 関数がまったく使用されないため、Is を使用します。バッファはありますか?これは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 などの以前の関数はコンテンツを出力しなくなることに注意してください。 作者は一度、print_r を介して ob_get_contents() の内容を出力しようとした後、その後のバッファー操作に影響を与えないように ob_clean() を呼び出してバッファーをクリアしようとしましたが、繰り返し失敗しました。よく考えてみると、print_rの内容が再度バッファに書き込まれ、後からob_clean()の操作が行われるため、当然出力はありません。 ob_clean 操作の前に ob_flush() 関数を呼び出すと、望ましい効果が得られます。
ob_flush() および flash()ob_flush() は、バッファーの内容を送信し、その内容を破棄します。したがって、この関数の前に ob_get_contents() を使用してバッファの内容を取得するのが最善です。 flash() はサーバー側のバッファをフラッシュしてクライアントに送信します。したがって、プロセスの観点からは、最初に ob_flush() を呼び出し、次にフラッシュ関数を呼び出す必要があります。さらに、Apache バッファ flash() の動作原理を説明しましょう。Apache モジュールの sapi の下で、flush は間接的に Apache の API: ap_rflush を使用し、sapi_module() のフラッシュ メンバー関数ポインタを呼び出すことで Apache の出力バッファをリフレッシュします。 。もちろん、mod_gzip などの他の Apache モジュールはこのアクションの結果を変更し、出力バッファ自体を実行する可能性があります。これにより、flush() 関数によって生成された結果がクライアント ブラウザにすぐに送信されなくなります。
ob_get_clean()
すでに ob_get_contents() と ob_clean に習熟している場合( ) の場合、この関数は非常に単純です。それは最初の 2 つを組み合わせたものだからです。主に現在のバッファの内容を取得し、現在の出力バッファを削除します。
ob 関数はたくさんありますが、そのほとんどは比較的簡単に使用でき、理解しやすいものです。詳細な説明があるphpマニュアルを参照してください。この記事では、筆者が最初はよく理解できなかった機能をいくつか挙げています。もちろん、将来的には新たな問題が発生するかもしれません。