PHP Flush/ob_flush 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4481235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 13:09:32  来源:igfitidea点击:

PHP Flush/ob_flush not working

phpbufferoutput-buffering

提问by JakeSmith

I've tried several attempts at getting my flush and ob_flush to work. I've tried setting the ini to allow buffering, I've tried using several different functions I found online for output buffering, and none of it at all is working. The script wants to wait until it is completly done until it echos output. Here is the script I have so far

我已经尝试了几次让我的flush 和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();

I want it to echo what it is doing, then run the function, then echo something else, then do another function. I want all the buffers to be flushed and echoed in real time on the browser.

我希望它回显它正在做什么,然后运行该函数,然后回显其他内容,然后执行另一个功能。我希望在浏览器上实时刷新和回显所有缓冲区。

回答by netcoder

The idea here is to disableoutput buffering, not enable it. As its name says, output buffering will save the output to memory and display it at the end of the script, or when explicitly asked for it.

这里的想法是禁用输出缓冲,而不是启用它。顾名思义,输出缓冲会将输出保存到内存中,并在脚本末尾或在明确要求时显示。

That being said, you don't have to flush explicitly for every output. Use the following, before displaying any output, and then you won't have to bother flushing every time you echo something:

话虽如此,您不必为每个输出显式刷新。在显示任何输出之前使用以下内容,然后每次回显时都不必费心冲洗:

ob_implicit_flush(true);
ob_end_flush();

Per example:

每个例子:

ob_implicit_flush(true);
ob_end_flush();

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

Will output, 0 to 4, with each being displayed every second.

将输出 0 到 4,每个每秒显示一次。

回答by Prusprus

I just wanted to write a quick note of what I've observed, now in 2016, of the different approached suggested:

我只是想快速记录一下我在 2016 年观察到的不同方法的建议:

The above codes offered by netcoderand Davidwork for me in the following browsers:

netcoderDavid提供的上述代码在以下浏览器中为我工作:

  • Chrome
  • Opera
  • 铬合金
  • 歌剧

It does not seem to work in Firefox, Safari, or IE 10-11.

它似乎不适用于 Firefox、Safari 或 IE 10-11。

I've also tested the alternative code:

我还测试了替代代码:

<?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();
?>

Which can be found here: http://php.net/manual/en/function.flush.php#54841

可以在这里找到:http: //php.net/manual/en/function.flush.php#54841

Which seems to have better current support through all browsers:

通过所有浏览器似乎有更好的当前支持:

  • Chrome
  • Firefox
  • Opera
  • Safari
  • IE 10
  • IE 11
  • 铬合金
  • 火狐
  • 歌剧
  • 苹果浏览器
  • 浏览器 10
  • 浏览器 11

The working implementations seem to change year to year, so I wanted to offer an update of what I've found myself to work at the moment.

工作实现似乎每年都在变化,所以我想提供我目前发现自己工作的更新。

回答by Maxime Fafard

Please note that you may need to disable gzip compression on your webserver (apache or nginx).

请注意,您可能需要在您的网络服务器(apache 或 nginx)上禁用 gzip 压缩。

It was my issue.

这是我的问题。

回答by David

This question seems to pop up a lot on a Google search, so I wanted to update it. It's September 2014.....

这个问题似乎在谷歌搜索中弹出了很多,所以我想更新它。现在是 2014 年 9 月......

@Netcoder 's answer does work, but Chrome will sometimes still output everything all at once.

@Netcoder 的答案确实有效,但 Chrome 有时仍会一次输出所有内容。

To fix this, simply added an ob_flush(), and flush()in the code, it will output after each second.

为了解决这个问题,只需在代码中添加一个ob_flush(),and flush()它将在每秒后输出。

Example:

例子:

ob_implicit_flush(true);
ob_end_flush();

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

回答by Imanuel Habekotte

<?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>

回答by user151496

this works now (at least on php 5.5)

这现在有效(至少在 php 5.5 上)

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

no need to sleep or anything else

无需睡觉或其他任何事情

回答by ner0

I have had the same problem but a user pointed me out in the right direction, I used a "for" loop to solve this browser specific issue:

我遇到了同样的问题,但用户指出了正确的方向,我使用“for”循环来解决此浏览器特定问题:

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

Relate to Outputting exec() ping result progressivelyfor more details.

涉及到逐步1.4.3 EXEC()平结果的更多细节。