web-dev-qa-db-ja.com

ob_flush()とflush()を呼び出しますが、スクリプトが終了するまでブラウザは出力を表示しません

こんにちは以下のコードをご覧ください:

<?php
ob_start();

echo "Start ...<br />\n";
for( $i = 0 ; $i < 10 ; $i++ )
{
    echo "$i<br />\n";
    ob_flush(); 
    flush();
    sleep(1);
}
echo "End ...<br />\n";
?>

それは間違っていますか?私はそれをテストしましたが、スクリプトが完了すると私の出力が表示されます、何か解決策はありますか?

20
DJafari

ねえ男私もこの問題で立ち往生し、最終的にここで正しい解決策を得ましたそれはあなたのためです

ページにコンテンツタイプを追加する必要があります。これは2つの方法で行うことができます。1。htmlタグを使用する

_<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
_

例.

_<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Wp Migration</title>
</head>
<body>
<?php 
for($i=0;$i<70;$i++)
{
echo 'printing...<br>';
ob_flush();
flush();
sleep(3);
}
?>
</body>
</html>
_
  1. phpヘッダー関数を使用する

    <?php header( 'Content-type: text/html; charset=utf-8' ); ?>

例.

_<?php 
header( 'Content-type: text/html; charset=utf-8' );
for($i=0;$i<70;$i++)
{
echo 'printing...<br>';
ob_flush();
flush();
sleep(3);
}
?>
_

ではごきげんよう

15
Rahul Shinde

一部のブラウザは、レンダリングを開始する前に少なくとも256文字を受け取る必要があります。次のような出力をさらに詰め込もうとしましたか?

_echo str_repeat('&nbsp;', 50) . "$i<br />\n";
_

[〜#〜]編集[〜#〜]

Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9の下で、設定することでOPの問題を再現することができました

_zlib.output_compression = On
_

で再びオフにします

_zlib.output_compression = Off
_

スクリプトを希望どおりに機能させました。

5
Jürgen Thelen

最初の行でob_start()の呼び出しを削除してみてください。出力バッファリングを有効にする必要はありません。おそらく、ここで問題が発生します。


私はあなたのコードをテストしました:

  • 最初の行でob_start()が呼び出された場合、スクリプトが終了したとき、10秒後に出力が表示されます。
  • ob_start()の呼び出しを削除すると、標準出力に表示されるとすぐに、毎秒1行の出力が表示されます。
3
Pascal MARTIN

Chromeを使用して、ブラウザのバッファをバイパスするためにさらに多くのバイトが必要であることがわかりました。私の場合、4096バイトで問題ありませんでした。

echo str_repeat(' ', 4096);

また、最初にHTML要素を追加することも必須のようです。

echo $content . '<br />';
2
Matthias Noback

私のシステムでは、FF4がサーバー側から到着するもののレンダリングを開始するために256バイト以上を必要とするようです、そして私は最初にこれで解決しました:

while (@ob_end_flush());
echo(str_repeat(' ',1024));
// ...etc...
1
Ulix

私の場合、これはApacheのgzip圧縮が使用されていることが原因であることがわかりました。

'flushing'スクリプトでのみgzipをオフにするために、次のように、連続出力スクリプトが存在するディレクトリに新しい.htaccessファイルを作成しました。

<IfModule mod_env.c>
    SetEnv no-gzip 1
</IfModule>

フラッシングは再び期待どおりに機能しています。

1
Josh Harrison

FCGI/fastcgiを使用している人向け。

FcgidOutputBufferSize 0
1
Alex S

IE8とflush()に関する1つの卑劣な問題。これは、テーブルの行を「フラッシュ」する場合です。 IEは、テーブルが完了したときにのみテーブルを表示します。これは私の問題であり、コンテナーをテーブル行からdivに変更することで問題が解決しました。

0

私はlaravelフレームワークを使用していますが、バッファリングは機能しませんでしたが、これが解決策です:

header( 'Content-type: text/html; charset=utf-8' );
ob_start();

ob_end_flush();
ob_flush();
flush();
for($i = 1;$i<= 5;$i++){
    echo $i;
    ob_flush();
    flush();

    sleep(3);
}

最初にob_end_flush();を使用する必要があります。

0
Ahmet Uğur

Gzip出力を無効にするには、.htaccessファイルを追加する必要があります

<IfModule mod_env.c>
    SetEnv no-gzip 1
</IfModule>
0
Dylan B

このフローはLaravel

ob_implicit_flush(true);
echo "Processing ... "; // Or give out JSON output
ob_flush();
sleep(5); //A time-consuming synchronous process (SMTP mail, maybe?)
echo "Done";
0
Deepak Thomas

正しいです。 PHP 5.3.3。それが機能しない場合は、PHPインストールで出力バッファリングが無効になっている可能性があります。

また、スクリプトの最後に ob_end_flush() を配置して、出力バッファーを閉じることをお勧めします。

0
Jason McCreary