ホームページ > バックエンド開発 > PHPチュートリアル > PHP はデータを 1 行ずつ出力し、バッファリングに関連する 2 つの一般的な問題を解決します

PHP はデータを 1 行ずつ出力し、バッファリングに関連する 2 つの一般的な問題を解決します

WBOY
リリース: 2016-06-13 12:14:33
オリジナル
1067 人が閲覧しました

PHP はデータを 1 行ずつ出力し、2 つの一般的なバッファリングの問題を解決します

このブロガーは、さまざまなインターネット技術に熱心で、しばしば強迫性障害を伴います。頻繁に更新しており、その記事が正しいと思われる場合は、フォローしてください。 「Dark Blue Sickle」と明記してください


1.

次の 2 つの状況に遭遇したことがあるのではないでしょうか:

  1. 上司は、データベース内のすべてのデータをブラウザに表示するよう求めています。データを比較する必要があるため、ページネーションは使用できないと要求しています。それでは、出力してください。ループ内で 1,000 個のデータを直接出力するのは問題ありませんが、データが数百万個ある場合はどうなるでしょうか?ブラウザがすぐにフリーズしてしまい、席を立ってコーヒーを飲みに行ったり、トイレに行ったりして、受付の人と長時間雑談をしていると、戻ってくるとブラウザが「プログラムが応答していません」と表示されます。どうすればいいでしょうか?
  2. 上司から、Web サイトのダウンロード リンクを改善するよう依頼されました。ファイルをダウンロードするにはマウスを直接左クリックする必要があります (一部のファイル タイプでは、直接左クリックするとファイルが開きます。多くの Web サイトでは、「右クリックして名前を付けて保存」するよう求められます)。header 関数と readfile 関数を使用してこれを簡単に実装しました。しかし、オンラインにアクセスした後、ファイルが大きすぎるとブラウザがスタックしてしまうことがわかりました。今度は上司がコーヒーを奢ろうとしているのですが、どうすればよいでしょうか?

上記の 2 つの状況に遭遇した場合、または将来そのような問題に直面する可能性がある場合は、次回すぐに解決できるようにマークを付けることができます。


2. 原則


仕事に戻ります。


以下は PHP 出力制御の壮大な紹介です 出力バッファ


まず、次のコードの効果を試してください


<?phpif (ob_get_level() == 0){ ob_start() }else{ exit(0);};//开始缓冲for ($i = 0; $i<10; $i++){    echo "Line to show.\n<br />";//不直接输出,先存入缓冲区中    ob_flush();//将缓冲区的数据输出出来    flush();//将缓冲区的数据输出出来    sleep(2);//暂停两秒}echo "Done.";ob_end_flush();//关闭并清理缓冲区
ログイン後にコピー

PHP にもこのような遅延読み込み機能が実装できるとは思いませんでした ですね。素晴らしい?


原則として、PHP はデータを出力する前にデータを バッファ に入れて待機します。必要に応じてバッファリングされたデータ。これを Cache と混同しないように注意してください。


これの利点は、一方では遅延読み込みと同様の優れた効果を実現できることですが、他方では、サーバーとクライアントの負荷を軽減しないと、出力に大きなデータがある場合、メモリが不足します。


注: ob_flush() および flush( ) はバッファ データをフラッシュするために使用されますが、公式の推奨事項は と組み合わせて使用​​することです。これは、ほとんどの Web サーバーでは ob_flush() のみが実行できるためですバッファをフラッシュしますが、Apache などの一部のケースでは、flush() を呼び出す必要がある場合があるため、コードの 移植性を確保するために、 は ob_flush()すぐにflush()を最後に追加します。


原理がわかったので、最初に述べた 2 つの問題を解いてみましょう。


3. 単一ページ内の数百万のデータの出力がスタックする問題を解決する

<?phpob_start();$data = [1,2,3,4,5,6,7,8,9,10];//实际数据更多,为方便距离假设浏览器一次输出10条会卡死$per = 3;//每次输出3条,可以改成1000 for ($i = 0;$i < count($data); $i+= $per){    for($j = $i; $j < $i + $per && $j <count($data); $j++){        echo $data[$j];    }    ob_flush();    flush();    sleep(2);}echo "Done.";ob_end_flush();
ログイン後にコピー


4.解决header实现文件下载时文件过大导致卡死的问题

<?phpheader('Content-type: application/txt');//输出类型ob_start();$data = "qwertyuioasdfghjkl";//文件内容,file_get_contents($file)$per = 15;//每次输出15个字符,可以改成1000或更大 for ($i = 0;$i < strlen($data); $i+= $per){    for($j = $i; $j < $i + $per && $j <strlen($data); $j++){        echo $data[$j];    }    sleep(2);    ob_flush();    flush();}echo "Done.";     ob_end_flush(); 
ログイン後にコピー

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート