PHP 刷新/ob_flush 不工作

发布于 2024-10-07 23:52:26 字数 1471 浏览 7 评论 0原文

我已经尝试了几次尝试让我的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'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

 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

仲春光 2024-10-14 23:52:26

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

话虽如此,您不必为每个输出显式刷新。在显示任何输出之前使用以下命令,这样您就不必在每次回显某些内容时都费心刷新:

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);
}

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

The idea here is to disable output 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.

雾里花 2024-10-14 23:52:26

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

netcoderDavid 提供的上述代码对我有用在以下浏览器中:

  • Chrome
  • Opera

它似乎不适用于 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

这似乎在所有浏览器中都有更好的当前支持:

  • Chrome
  • Firefox
  • Opera
  • Safari
  • IE 10
  • IE 11

工作实现似乎每年都在变化,所以我我想提供我目前工作的最新情况。

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

The above codes offered by netcoder and David work for me in the following browsers:

  • Chrome
  • Opera

It does not seem to work in Firefox, Safari, or 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

Which seems to have better current support through all browsers:

  • Chrome
  • Firefox
  • Opera
  • Safari
  • IE 10
  • IE 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.

梦在夏天 2024-10-14 23:52:26

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

这是我的问题。

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

It was my issue.

挽袖吟 2024-10-14 23:52:26
<?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>
<?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>
§对你不离不弃 2024-10-14 23:52:26

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

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

要解决这个问题,只需在代码中添加一个 ob_flush()flush() ,它就会在每秒后输出。

例子:

ob_implicit_flush(true);
ob_end_flush();

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

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

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

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

Example:

ob_implicit_flush(true);
ob_end_flush();

for ($i=0; $i<5; $i++) {
    echo $i.'<br>';
    ob_flush();
    flush();   
    sleep(1);
}   
狠疯拽 2024-10-14 23:52:26

更新为 2021 年,

基本上使用了 Imanuel Habekotte 的解决方案

我遇到了同样的问题,我在 .htaccess 文件中

SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI .*/my_file_name.php$ no-gzip dont-vary

;然后在我的php代码文件(my_file_name.php)中;

header('Content-Type: text/octet-stream; charset=utf-8');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.


    ini_set('max_execution_time', 0);
    @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();
    ob_implicit_flush(true);


/**
    Send a partial message
*/
function send_message($id, $message, $progress) 
{
    $d = array('message' => $message , 'progress' => $progress);
    
    echo json_encode($d) . PHP_EOL;
    
    echo str_pad('',8192)."\n";
    
    //PUSH THE data out by all FORCE POSSIBLE
    ob_flush();
    flush();
}

Updated for 2021

I had this same problem and I used basically the solution from Imanuel Habekotte

in my .htaccess file;

SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI .*/my_file_name.php$ no-gzip dont-vary

Then in my php code file (my_file_name.php);

header('Content-Type: text/octet-stream; charset=utf-8');
header('Cache-Control: no-cache'); // recommended to prevent caching of event data.


    ini_set('max_execution_time', 0);
    @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();
    ob_implicit_flush(true);


/**
    Send a partial message
*/
function send_message($id, $message, $progress) 
{
    $d = array('message' => $message , 'progress' => $progress);
    
    echo json_encode($d) . PHP_EOL;
    
    echo str_pad('',8192)."\n";
    
    //PUSH THE data out by all FORCE POSSIBLE
    ob_flush();
    flush();
}
我早已燃尽 2024-10-14 23:52:26

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

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

涉及 逐步输出 exec() ping 结果了解更多详细信息。

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($i = 0; $i < 5000; $i++)
{
    echo ' ';
}

Relate to Outputting exec() ping result progressively for more details.

司马昭之心 2024-10-14 23:52:26

现在可以工作了(至少在 php 5.5 上)

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

不需要睡觉或其他任何事情

this works now (at least on php 5.5)

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

no need to sleep or anything else

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文