バッファ
バッファはメモリのアドレス空間で、Linux システムのデフォルトのサイズは通常 4096 (4kb) で、これは 1 つのメモリ ページです。主に、速度が同期していないデバイスや優先度が異なるデバイス間のデータ転送領域を格納するために使用されます。バッファーを介して、プロセスは相互に待機する時間を減らすことができます。次に、より一般的な例を示します。ファイルを編集するためにテキスト エディタを開いた場合、文字を入力するたびに、オペレーティング システムはその文字をすぐにディスクに直接書き込むのではなく、書き込み時に最初にその文字をバッファに書き込みます。バッファがいっぱいの場合、バッファ内のデータはディスクに書き込まれます。もちろん、カーネル関数 flash() が呼び出されるときは、バッファ内のダーティ データをディスクに書き戻す必要があります。
同様に、echo と print が実行されると、出力は tcp 経由で表示するためにクライアントのブラウザにすぐに送信されませんが、データは PHP バッファに書き込まれます。 phpのoutput_bufferingメカニズムは、tcpバッファの前に新しいキューが確立され、データがそのキューを通過する必要があることを意味します。 PHP バッファーがいっぱいになると、スクリプト プロセスは PHP バッファー内の出力データをシステム カーネルに渡し、表示のために TCP 経由でブラウザーに渡します。したがって、データは echo/pring -> php バッファ -> tcp バッファ -> ブラウザの順に書き込まれます。
phpのoutput_buffering
デフォルトでは、php バッファーがオンになっており、バッファーのデフォルト値は 4096、つまり 4kb です。 Output_buffering 設定は php.ini 設定ファイルにあります。echo、print などでユーザー データを出力すると、output_buffering がいっぱいになるまで、データは php の out_buffering に書き込まれます。 。 見せる。 ob_start() を使用して php の出力バッファリングメカニズムを手動でアクティブにすることもできます。これにより、出力が 4kb のデータを超えた場合でも、ob_start() が php バッファスペースを次のように設定するため、データは実際には tcp に渡されず、ブラウザに渡されます。十分な大きさであること。スクリプトが終了するか、ob_end_flush 関数が呼び出されるまで、データはクライアント ブラウザに送信されません。1.output_buffering=4096 で、出力するデータが少ない場合 (バッファー 1 つ未満)
2、output_buffering=0 の場合、出力するデータは少なくなります (1 バッファ未満)。
コードをコピー
コードは次のとおりです:
sleep($i +1);現象: 応答が終了しておらず (http 接続が閉じられていない)、断続的な出力が断続的に表示され、ブラウザーのインターフェイスが空白のままになりません。 phpのoutput_bufferingメカニズムが有効になっていますが、output_bufferingスペースが十分ではないため、1回限りの出力ではなく断続的な出力が依然として存在します。 PHP バッファリングがいっぱいになるたびに、データがクライアント ブラウザに送信されます。 4. Output_buffering=4096 の場合、出力データは 1 つの TCP バッファーより大きいため、ob_start() を呼び出します
現象: サーバー側のスクリプトの処理が完了し、応答が終了するまで、完全な出力が表示されません。出力間隔が非常に短く、一時停止を感じられません。出力前に、ブラウザは空のインターフェイスを維持し、サーバー データを待ちます。これは、PHP が ob_start() 関数を呼び出すと、ob_end_flush 関数が呼び出されるかスクリプトが終了するまで、PHP バッファーが十分なサイズに拡張されるためです。
tcpdump の観察
ここでは、tcpdump を通じて tcp メッセージを監視し、ob_start() を使用した場合と使用しない場合の違いを観察します。
1. ob_start() を使用しない
12:30:21.499528 IP 192.168.0.8.webcache > 192.168.0.28.cymtec-port: . ack 485 win 6432 12:30:21.500127 IP 192.168.0.8.webcache > 192.168 0.28.cymtec ポート: 1:2921(2920) ack 485 勝利 6432 12:30:21.501000 IP 192.168.0.28.cymtec ポート: 2921:7301(4380) 85 6勝432 12 :30:21.501868 IP 192.168.0.8.webcache > 192.168.0.28.cymtec-port: P 7301:8412(1111) ack 485 win 643 12:30:24.502340 IP 192.168.0.8.webcache > .168.0.28 .cymtec-ポート: .8412:14252(5840) ack 485 win 6432 12:30:24.503214 IP 192.168.0.8.webcache > 14252:15712(1460) ack 48 5勝6432 12: 30:24.503217 IP 192.168.0.8.webcache > 192.168.0.28.cymtec-port: P 15712:16624(912) ack 485 win 6432 12:30:31.505934 IP 192.168.0.8.webcache > 192.168.0.28 .cymtec-ポート: 16624 :23924(7300) ACK 485 勝利 6432 12:30:31.506839 IP 192.168.0.8.webcache > 192.168.0.28.cymtec ポート: P 23924:24836(912) ACK 485 勝利 6432 12:30:42.50 8871 IP 192.168.0.8.webcache > 192.168.0.28.cymtec-port: 24836:32136(7300) ack 485 win 6432 12:30:42.509744 IP 192.168.0.8.webcache > 192.168.0 .28.cymtecポート: P 321 36:33048(912) ACK 485 勝利 6432 12:30:57.512137 IP 192.168.0.8.webcache > 192.168.0.28.cymtec ポート: 33048:40348(7300) ACK 485 勝利 6432 12:30 :57.513016 IP 192 。 168.0.8.webcache > 192.168.0.28.cymtec-port: P 40348:41260(912) ack 485 win 6432 12:31:06.513912 IP 192.168.0.28.cymtec-port :P41260: 41265(5) ACK 485 勝利 6432 12:31:06.514012 IP 192.168.0.8.webcache > 192.168.0.28.cymtec-port: F 41265:41265(0) ACK 485 勝利 6432 12:31:06.514361 IP 192.168.0.8。 webcache > 192.168.0.28。 ack 486 win 6432
2. IP 192.168.0.28.noagent: を使用しました。 85勝 6432 12: 36:51.559128 IP 192.168.webcache > 192.168.0.28.noagent: 1:2921(2920) ack 485 win 6432 12:36:51.559996 IP 192.168.0.8.webcache > 19 2.168.0.28.noagent: .2921: 730 1(4380)ack 485 勝利 6432 12:36:51.560866 IP 192.168.0.8.webcache > 192.168.0.28.noagent: 7301:11681(4380) ack 485 勝利 6432 12:36:51.561 612 IP 192.168.0.8.webキャッシュ > 192.168.0.28.noagent: 11681:16061(4380) ack 485 win 6432 12:36:51.561852 IP 192.168.0.28.noagent: 20441(4380) ACK 485 勝利 6432 12 :36:51.562479 IP 192.168.webcache > 192.168.0.28.noagent: . 20441:24821(4380) ack 485 win 6432 12:36:51.562743 IP 192.168.0.8.webc痛み > 192.168.0.28.noagent: 。 21:29201(4380)ack 485 勝利 6432 12:36:51.562996 IP 192.168.0.8.webcache > 192.168.0.28.noagent: 29201:33581(4380) ack 485 勝利 6432 12:36:51 .563344 IP 192.168.0.8。 webcache > 192.168.0.28.noagent : P 33581:35041(1460) ack 485 win 6432 12:36:51.563514 IP 192.168.0.28.noagent: 。 36501(1460) 確認応答 485 勝利 6432 12: 36:51.563518 IP 192.168.webcache > 192.168.0.28.noagent: . 36501:37961(1460) ack 485 win 6432 12:36:51.563523 IP 192.168.0.8.webc痛み > 192.168.0.28.noagent: 。 379 61:39421(1460) ACK 485 勝利 6432 12:36:51.563526 IP 192.168.0.8.webcache > 192.168.0.28.noagent: 39421:40881(1460) ACK 485 勝利 6432 12:3 6:51.563529 IP 192.168.0.8 .webcache > 192.168.0.28.noagent : FP 40881:41233(352) ack 485 win 6432 12:36:51.570364 IP 192.168.0.28.noagent: 。 86勝6432
上記比較より、データパケットの時間間隔が明らかに異なることがわかります。 ob_start() を使用しない場合、時間間隔は比較的長く、TCP バッファ内のデータは約 4 秒待ってから送信されます。データは PHP バッファーに長時間留まらず、出力データはクライアントのブラウザーに送信されます。これは、PHP バッファがすぐにいっぱいになり、データを送信する必要があるためです。 ob_start() が有効な場合は、データ パケットがほぼ同時にクライアントに送信されます。 PHP バッファ内のデータがクライアント ブラウザに送信される前に ob_end_flush() が呼び出されるまで、データは PHP バッファ内に留まると推測できます。
出力バッファリング関数
1.ob_start
は、output_bufferingメカニズムをアクティブにします。アクティブ化すると、スクリプト出力はブラウザに直接送信されなくなり、一時的に PHP バッファ メモリ領域に書き込まれます。
phpはデフォルトでoutput_bufferingメカニズムを有効にしますが、ob_start()関数を呼び出すことにより、データのoutput_buffering値が十分に大きな値に拡張されます。 $chunk_size を指定して、output_buffering の値を指定することもできます。 $chunk_size のデフォルト値は 0 です。これは、スクリプトが終了するまで php バッファー内のデータがブラウザーに送信されないことを意味します。 $chunk_size のサイズを設定すると、バッファ内のデータ長がこの値に達する限り、バッファ内のデータがブラウザに送信されることを意味します。
もちろん、$ouput_callbackを指定することでバッファ内のデータを処理することもできます。たとえば、関数 ob_gzhandler はバッファ内のデータを圧縮してブラウザに送信します。
2.ob_get_contents
PHP バッファ内のデータのコピーを取得します。 ob_end_clean() 関数が呼び出される前にこの関数を呼び出す必要があることに注意してください。そうしないと、ob_get_contents() は null 文字を返します。
3. ob_end_flush と ob_end_clean
これら 2 つの関数は似ており、両方とも ouptu_buffering メカニズムをオフにします。ただし、違いは、ob_end_flush は php バッファー内のデータをクライアント ブラウザーにフラッシュ (フラッシュ/送信) するだけですが、ob_clean_clean は php バッファー内のデータをクリア (消去) しますが、クライアント ブラウザーには送信しないことです。 ob_end_flush が呼び出された後も、php バッファー内のデータはまだ存在しており、ob_get_contents() は引き続き php バッファー内のデータのコピーを取得できます。 ob_end_clean() を呼び出した後、ob_get_contents() は空の文字列を取得し、ブラウザは出力を受け取ることができません。つまり、出力はありません。
使用例
一部のテンプレート エンジンやページ ファイル キャッシュで ob_start() が使用されているのがよく見られます。それらの痕跡は、wordpress、drupal、smarty などの有名なオープンソース プロジェクトで見つけることができます。ここではdrupalのアプリケーションを紹介します。
テンプレートファイル
http://www.bkjia.com/PHPjc/728097.html