ホームページ  >  記事  >  バックエンド開発  >  PHP バッファリングの使用の概要、output_buffering および ob_start_PHP チュートリアル

PHP バッファリングの使用の概要、output_buffering および ob_start_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:39:471268ブラウズ

バッファ

バッファはメモリのアドレス空間で、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 つ未満)

コードをコピー コードは次のとおりです:
for ($i = 0; $i < 10; $i++) {
echo $i '
sleep//
}
?>

現象: 数秒ごとに断続的に出力されるのではなく、サーバー スクリプトの処理が完了するまで、ブラウザー インターフェイスは空白のままになります。これは、データ量が少なすぎてphpのoutput_bufferingがいっぱいになっていないためです。データの書き込み順序は、echo->php バッファ->tcp バッファ->ブラウザ

2、output_buffering=0 の場合、出力するデータは少なくなります (1 バッファ未満)。

コードをコピーします コードは次のとおりです:
//ini_set('output_buffering', 0) を渡しても有効になりません
///etc/php.ini を編集する必要がありますそして、出力バッファリング機構を無効にするために、output_buffering=0 を設定します
//ini_set('output_buffering', 0); //出力バッファリング関数を完全に無効にします
for ($i = 0; $i <10; $i++) {
echo $i '
;a href="http://www.php.net/sleep">sleep($i + 1); //
}
?>


現象: 先ほどの表示と一致しません。PHP バッファリング メカニズムを無効にすると、ブラウザに断続的な出力が表示され、スクリプトが実行されるまで待つ必要はありません。これは、phpのoutput_bufferingにデータが残らないためです。データの書き込み順序はecho->tcpバッファ->ブラウザ
3.output_buffering=4096.の場合、出力データが1バッファより大きい場合、ob_start()は呼び出されません
4kbファイルを作成します$dd if=/dev /zero of=f4096 bs=4096 count=1




コードをコピー

コードは次のとおりです:

for ($i = 0; $i < 10; $i++) { echo file_get_contents('./f4096') . $i . '
';
sleep($i +1);
}
?>

現象: 応答が終了しておらず (http 接続が閉じられていない)、断続的な出力が断続的に表示され、ブラウザーのインターフェイスが空白のままになりません。 phpのoutput_bufferingメカニズムが有効になっていますが、output_bufferingスペースが十分ではないため、1回限りの出力ではなく断続的な出力が依然として存在します。 PHP バッファリングがいっぱいになるたびに、データがクライアント ブラウザに送信されます。 4. Output_buffering=4096 の場合、出力データは 1 つの TCP バッファーより大きいため、ob_start() を呼び出します

コードをコピーします コードは次のとおりです:

ob_start() ; //php バッファを開く
for ($i = 0; $i echo file_get_contents';
sleep + 1);
}
ob_end_flush();
?>

現象: サーバー側のスクリプトの処理が完了し、応答が終了するまで、完全な出力が表示されません。出力間隔が非常に短く、一時停止を感じられません。出力前に、ブラウザは空のインターフェイスを維持し、サーバー データを待ちます。これは、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のアプリケーションを紹介します。
テンプレートファイル

コードをコピーします コードは次のとおりです:

//@file:user-profile.tpl.php

< ->< ;/li> ;
;
  • picture:picture; ?

  • div>

    //@file:template-render.php
    function theme_render_template($template_file, $variables) {
    if (!is_file($template_file) { return ""; }
    extract($variables, EXTR_SKIP );
    ob_start();
    $contents = ob_get_contents();
    ob_end_clean();
    return $contents;
    }
    ?>

    //@file:profile.php
    $変数 = array('user ' => $user);
    print theme_render_template('user-profile.tpl.php ', $変数);
    ?>


    http://www.bkjia.com/PHPjc/728097.html

    tru​​ehttp://www.bkjia.com/PHPjc/728097.html技術記事バッファ バッファはメモリ アドレス空間であり、Linux システムのデフォルト サイズは通常 4096 (4kb) で、これは 1 メモリ ページです。主に、ストレージ速度が同期していないデバイスや、優先順位が異なるデバイスに使用されます...
    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。