web-dev-qa-db-ja.com

PHP Apache / Linuxでの出力バッファフラッシュの問題

LinuxWebサーバーでのPHP出力バッファーのフラッシュで問題が発生しています。出力バッファーは正しく維持され、すべての正しいデータがコードにプッシュされますが、通常のフラッシュです。メカニズムはそれをブラウザにフラッシュしません。私はここに投稿されたすべてを試しました: http://php.net/manual/en/function.flush.php しかし、これまでのところ成功していません。

私はそれをテストするためにphp.netから小さなスクリプトを入手しました:

<?php
    ob_start();
    for($i=0;$i<70;$i++)
    {
        echo 'printing...<br />';
        ob_get_flush();
        flush();
        usleep(300000);
    }
?>

これにより、「printing ...」がブラウザに70回、3秒ごとに1行印刷されます。これは、Windowsに基づく他のテスト環境(まだApache、XAMPPパッケージを使用)では正常に機能しますが、Linuxサーバーでは機能しません。スクリプトが完了するのを待ってからブラウザに何かを与え、基本的にはフラッシュコマンド全体を無視します。

誰かがこれを以前に経験したことがある、または役立つ可能性があることを知っている場合(サーバーの構成やコードの調整など)、それは大歓迎です!

6

私はこの問題を抱えていて、次の行を見つけました:

while ( @ob_end_flush() ); // even if there is no nested output buffer
flush();

問題を解決します。

結果は異なる場合があります。これは、IEおよびApache2.0.55を使用する私のシステムで機能します。

ジェフ

2
Pacific Voyager

PHPの出力バッファーのフラッシュとApacheのバッファーのフラッシュは、2つの異なるタスクです。 PHPの出力バッファーをフラッシュしても、データが増えるまでApacheからブラウザーに何も送信されないことがよくあります。また、ブラウザは十分なデータを受信するまで何も表示しない場合があります。試すことができるのは、出力に改行を「埋め込む」ことです。

投稿したコードには他に2つの問題があります。まず、出力バッファリングを1回開始し、次にループ内で複数回終了します。ループの内側にも出力バッファリングが必要な場合、または単に省略する場合もあります。もう1つの問題は、ob_get_flush()が出力バッファーの内容をエコーではなく、文字列として返すことです。

代わりにこのコードを試してください:

<?php
    for($i=0;$i<70;$i++)
    {
        echo 'printing...<br />';
        echo str_repeat("\n",1024);
        flush();
        usleep(300000);
    }
?>

PHPマニュアルから:

flush()は、Webサーバーのバッファリングスキームをオーバーライドできない場合があり、ブラウザのクライアント側のバッファリングには影響しません。 [...]

Mod_gzipのようなApacheのサーバーモジュールは独自のバッファリングを行う場合があり、flush()によってデータがクライアントにすぐに送信されないようになります。

ブラウザでさえ、表示する前に入力をバッファリングする場合があります。たとえば、Netscapeは、行末またはタグの先頭を受け取るまでテキストをバッファし、最も外側のテーブルのタグが見つかるまでテーブルをレンダリングしません。

Microsoft Internet Explorerの一部のバージョンは、256バイトの出力を受信した後にのみページの表示を開始するため、これらのブラウザーでページを表示するには、フラッシュする前に余分な空白を送信する必要があります。

私の例では、1024個の改行を送信してこれを回避しようとしています。

1
Josh

PHPのドキュメントに記載されているように、私の経験では、これの一般的な原因はApacheのmod_gzipによる出力バッファリングです。多くのディストリビューションでは、これがデフォルトで有効になっています。

マーク

1
mfarver