以下は、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=>php Output_buffering=>webServerbuffer=>browserbuffer=>ブラウザ表示
関数からクライアントに情報を送信するまでに 2 つのバッファーを通過し、クライアントはブラウザーのバッファーも通過していることがはっきりとわかります。この記事で主に説明するのは php Output_buffering です。 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() と flash()
ob_flush()はバッファの内容を送信し、その内容を破棄します。したがって、この関数の前に ob_get_contents() を使用してバッファの内容を取得するのが最善です。 flash() はサーバー側のバッファをフラッシュしてクライアントに送信します。したがって、プロセスの観点からは、最初に ob_flush() を呼び出し、次にフラッシュ関数を呼び出す必要があります。
さらに、Apachebuffer flash()の動作原理を説明しましょう: apache moduleのsapiの下で、flushは間接的にApacheのapi: ap_rflushを使用して、sapi_module(のflushメンバー関数ポインタを呼び出すことでApacheをリフレッシュします) ) 出力バッファ。もちろん、mod_gzip などの他の Apache モジュールはこのアクションの結果を変更する可能性があり、出力バッファー自体を実行する可能性があります。その場合、flush() 関数によって生成された結果がクライアントのブラウザーにすぐに送信されなくなります。
コードをコピーします コードは次のとおりです:
ob_get_clean()
すでにob_get_contents()とob_clean()に精通している場合、この関数は非常に簡単です。それは最初の 2 つを組み合わせたものだからです。主に現在のバッファの内容を取得し、現在の出力バッファを削除します。
ob 関数は他にもたくさんありますが、そのほとんどは比較的使いやすく、理解しやすいものです。詳細な説明があるphpマニュアルを参照してください。この記事では、筆者が最初はよく理解できなかった機能をいくつか挙げています。もちろん、将来的には新たな問題が発生するかもしれません。
上記の内容は、この記事で PHP の ob 関数のバッファリング メカニズムを深く理解したものであり、将来的に皆さんのお役に立つことを願っています。