php.iniを変更した後は、Apacheサービスラインを再起動する必要があることに注意してください。
for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
PHP キャッシュ出力制御関数について学習したことがある方は、このコードが達成したい効果は 1 秒ごとに数値を出力することであることをご存知でしょう。ただし、出力全体を完了するには 10 秒かかります。実際に実行すると、人によっては期待どおりに動作するのに、10 秒後に一度に 10 個の数値が出力されるという奇妙な現象が発生することがあります。私は以前、この問題に夢中になっていましたが、この状況は、IE のキャッシュが 256 文字に達しないと出力できないためであるとメッセージを残していました。動作しない状態。今日マニュアルを注意深く読んだところ、これらの予期せぬ現象には理由があることがわかりました。
php.ini には、php のキャッシュ出力制御に影響を与える 2 つの重要なパラメータがあることがわかりました:
パラメータ 1: Output_buffering: on/off または integer。オンに設定すると、出力キャッシュ コントロールはキャッシュのサイズを制限せずにすべてのスクリプトで使用されます。 Output_buffering=4096 などの整数に設定すると、キャッシュ データ が 4096 バイトに達すると、キャッシュが自動的に出力され、更新されます。このパラメータの違いが、上記のコードの実行結果が異なるタイミングで異なる理由です。 Output_buffering がオフになっている場合、スクリプトのすべての出力 (エコー) は、上記のコードが実行されるとすぐにクライアントに送信され、1 秒ごとに数値が出力されます。 Output_buffering をオンにすると、出力コンテンツは最初にサーバーにキャッシュされ、スクリプトが終了するまでクライアントに送信されません。
パラメータ 2: implicit_flush: オン/オフ。 ON に設定すると、スクリプトが出力されるとすぐに自動的にクライアントに送信されます。これは、echo の後に flash() を自動的に追加するのと同じです。
PHP キャッシュ出力制御の関連関数:
ob_start()
最初のパラメータ: コールバック関数、オプション。出力は、キャッシュされる前にフィルタリングまたはその他の方法で処理できます。最も一般的な使用法は ob_start('ob_gzhandler') で、キャッシュされたデータをクライアントに送信する前に gzip 圧縮します。
2 番目のパラメーター: キャッシュ ブロックのサイズ (オプション)。キャッシュされたコンテンツがキャッシュ ブロック サイズに達するか操作されると、キャッシュは自動的に削除されます。デフォルト値は 0 です。これは、サイズが制限されず、キャッシュが最後までキャッシュされることを意味します。 chunk_size=4096 を表す特別な値 1 もあります。
3 番目のパラメータ: キャッシュをクリアするかどうか。オプション。デフォルトは true です。false に設定すると、スクリプトの実行が終了する前にキャッシュはクリアされません。
ob_get_contents() を使用してサーバー側のキャッシュされたデータを文字列の形式で取得し、ob_end_flush() を使用してキャッシュされたデータを出力し、キャッシュを閉じることができます。
ob_end_clean() を使用すると、データやその他のアクションを行わずに、サーバーにキャッシュされたデータがサイレントに消去されます。
サーバー側のキャッシュはスタックされています。つまり、ob_start() を有効にした後、それを閉じる前に、その中にある別のキャッシュ ob_start() を開くこともできます。ただし、キャッシュをオンにする操作と同じ数のキャッシュをオフにする操作があることも確認する必要があります。
ob_start() は、キャッシュされたデータを処理するコールバック関数を指定できます。1 つの ob_start() が別の ob_start() 内にネストされている場合、外側の ob_start() には A という番号が付けられ、内側の層はob_start() の番号は B です。それぞれに functionA と functionB というコールバック関数があります。B のデータがキャッシュされて出力されると、まず funcitonB コールバック関数によって処理され、次に外側の functionA コールバックに渡されます。関数を使用して処理すると、クライアントに出力できます。さらに、マニュアルには、Apache などの一部の Web サーバーでは、コールバック関数を使用すると、プログラムの現在の作業ディレクトリが変更される可能性があると記載されています。解決策は、コールバック関数で作業ディレクトリを手動で変更して使用することです。 chdir 関数、これは頻繁に発生するものではないようですが、発生した場合は必ずマニュアルを確認してください。
flush() と ob_flush()
これら 2 つの関数の使用法は、おそらく多くの人にとって最も混乱する問題です。マニュアル内の 2 つの関数の説明も明確ではなく、それらの違いは明確に指摘されていません。両方の機能は出力キャッシュを更新することであるようです。しかし、記事の冒頭のコードで、flush() が ob_flush() に置き換えられると、プログラムは正しく実行されなくなります。明らかに、それらの間に違いがあります。そうでない場合は、それらの一方が別の関数のエイリアスであることをマニュアルに直接記載するだけで十分です。それらを個別に説明する必要はありません。それでは、それらの違いは何でしょうか?
反复研究了手册的说明,参考了手册中一些人的留言,自己琢磨应该是这样的:
在没有开启缓存时,脚本输出的内容都在服务器端处于等待输出的状态,flush()可以将等待输出的内容立即发送到客户端。
开启缓存后,脚本输出的内容存入了输出缓存中,这时没有处于等待输出状态的内容,你直接使用flush()不会向客户端发出任何内容。而ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端,这时你就需要先使用ob_flush()再使用flush(),客户端才能立即获得脚本的输出。
也就是说本文开头的脚本,可以根据缓存开启与否,有如下几种不同的写法:
注:以下代码都未考虑IE缓存必须大于256字节才输出的问题,如在IE下测试,请在代码开始加一句:“echo str_repeat('',256)”
写法1:
output_buffering = off implicit_flush=off for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法2:
output_buffering = on implicit_flush=off for($i=0;$i<10;$i++) { echo $i.'<br />'; ob_flush(); flush(); sleep(1); }
写法3:
output_buffering = off implicit_flush=off ob_start(); for($i=0;$i<10;$i++) { echo $i.'<br />'; ob_flush(); flush(); sleep(1); }
写法4:
output_buffering = on implicit_flush=off ob_end_flush(); for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法5:
output_buffering = on implicit_flush=off ob_end_clean(); for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法6:
output_buffering = on; implicit_flush=on ob_end_clean(); // 或者ob_end_flush(); for($i=0;$i<10;$i++) { echo $i.'<br />'; sleep(1); }
写法7:
output_buffering = on; implicit_flush=on ob_end_clean(); // 或者ob_end_flush(); for($i=0;$i<10;$i++) { echo $i.'<br />'; flush(); sleep(1); }
写法8:
output_buffering = off implicit_flush=on for($i=0;$i<10;$i++) { echo $i.'<br />'; sleep(1); }
以上がPHP出力キャッシュ関数ob_start、flush、ob_flushの使い方の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。