12

フラッシュとob_flushを機能させるためにいくつかの試みを試みました。バッファリングを許可するように ini を設定しようとしました。出力バッファリングのためにオンラインで見つけたいくつかの異なる関数を使用してみましたが、どれもまったく機能していません。スクリプトは、出力がエコーされるまで、完全に完了するまで待機したいと考えています。ここに私がこれまでに持っているスクリプトがあります

 ob_start();

 //Login User
 echo 'Logging in to user<br>';
       ob_flush();
       flush();
      $ch = curl_init("http://www.mysite.com/login/");
      curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, "username=$user&pass=$pass");
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
      curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies/$cookie");
      curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies/$cookie");
      $output = curl_exec($ch);
      curl_close($ch);
      ob_flush();
      flush();

       //Update Status
 echo 'Updating Status<br>';
       ob_flush();
       flush();
      $ch = curl_init("http://www.mysite.com/update/");
      curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, "status=$status");
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
      curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies/$cookie");
      curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies/$cookie");
      $output = curl_exec($ch);
      curl_close($ch);
      ob_flush();
      flush();

私はそれが何をしているのかをエコーし​​ てから、関数を実行し、次に何か他のことをエコーし​​、次に別の機能を実行したいと考えています。ブラウザ上ですべてのバッファをリアルタイムでフラッシュしてエコーする必要があります。

4

8 に答える 8

46

ここでの考え方は、出力バッファリングを有効にするのではなく、無効にすることです。その名前が示すように、出力バッファリングは出力をメモリに保存し、スクリプトの最後または明示的に要求されたときに表示します。

そうは言っても、出力ごとに明示的にフラッシュする必要はありません。出力を表示する前に次を使用すると、何かをエコーするたびにわざわざフラッシュする必要がなくなります。

ob_implicit_flush(true);
ob_end_flush();

例:

ob_implicit_flush(true);
ob_end_flush();

for ($i=0; $i<5; $i++) {
   echo $i.'<br>';
   sleep(1);
}

1秒ごとに0~4を出力します。

于 2010-12-19T04:28:03.127 に答える
9

2016 年現在、提案されているさまざまなアプローチについて、私が観察したことの簡単なメモを書きたいと思います。

netcoderDavidが提供する上記のコードは、次のブラウザーで機能します。

  • クロム
  • オペラ

Firefox、Safari、または IE 10-11 では動作しないようです。

代替コードもテストしました:

<?php

    if (ob_get_level() == 0) ob_start();
    for ($i = 0; $i<10; $i++){

        echo "<br> Line to show.";
        echo str_pad('',4096)."\n";    

        ob_flush();
        flush();
        sleep(2);
    }

    echo "Done.";

    ob_end_flush();
?>

ここで見つけることができます: http://php.net/manual/en/function.flush.php#54841

現在、すべてのブラウザでより優れたサポートを提供しているようです:

  • クロム
  • ファイアフォックス
  • オペラ
  • サファリ
  • IE10
  • IE11

動作する実装は年々変化しているように見えるので、現在動作しているとわかったものの最新情報を提供したいと思いました。

于 2016-01-25T15:44:32.540 に答える
5

ウェブサーバー (apache または nginx) で gzip 圧縮を無効にする必要がある場合があることに注意してください。

それは私の問題でした。

于 2016-09-24T21:25:37.130 に答える
3
<?php
    header('Content-Type: text/html; charset=utf-8');

    // I think maybe you can set output_buffering using ini_set here, but I'm not sure.
    // It didn't work for me the first time at least, but now it does sometimes...
    // So I set output_buffering to Off in my php.ini,
    // which normally, on Linux, you can find at the following location: /etc/php5/apache2/php.ini

    @ini_set('output_buffering','Off');
    @ini_set('zlib.output_compression',0);
    @ini_set('implicit_flush',1);
    @ob_end_clean();
    set_time_limit(0);
    ob_start();

    //echo str_repeat('        ',1024*8); //<-- For some reason it now even works without this, in Firefox at least?
?>
<!DOCTYPE html>
<html>
    <head>
        <title>PHP Flushing</title>
    </head>
    <body>
        <h1>Flushing the webpage in real-time using PHP.</h1>
<?php
    ob_flush();
    flush();

    //Note: ob_flush comes first, then you call flush. I did this wrong in one of my own scripts previously.
    for($i=0; $i<5; $i++) {
        echo $i.'<br>';
        ob_flush();
        flush();   
        sleep(1);
    }
?>
    </body>
</html>
于 2016-09-06T13:45:50.610 に答える
2

この質問は Google 検索でよく出てくるようなので、更新したいと思いました。2014年9月です.....

@Netcoder の答えは機能しますが、Chrome はすべてを一度に出力することがあります。

これを修正するには、コードに , を追加するだけで、1 秒ごとに出力されますob_flush()and flush()

例:

ob_implicit_flush(true);
ob_end_flush();

for ($i=0; $i<5; $i++) {
    echo $i.'<br>';
    ob_flush();
    flush();   
    sleep(1);
}   
于 2014-09-05T02:43:23.503 に答える
0

私は同じ問題を抱えていましたが、ユーザーが正しい方向を指摘してくれました。「for」ループを使用して、このブラウザー固有の問題を解決しました。

for($i = 0; $i < 5000; $i++)
{
    echo ' ';
}

詳細については、 exec() ping の結果をプログレッシブに出力するを参照してください。

于 2012-05-30T11:32:10.553 に答える
0

これは現在動作します (少なくとも php 5.5 では)

ob_end_flush();
while(stuff){
  ..stuff...
  echo('yo');
  flush();
}

寝る必要も何もない

于 2015-07-04T10:44:50.537 に答える