【问题标题】:Echo 'string' while every long loop iteration (flush() not working)每次长循环迭代时回显“字符串”(flush()不起作用)
【发布时间】:2011-09-27 06:13:57
【问题描述】:

我有一个执行时间很长的循环,我希望脚本在循环迭代完成时显示一些内容。

echo "Hello!";

flush();

for($i = 0; $i < 10; $i ++) {
    echo $i;
    //5-10 sec execution time
    flush();
}

在整个脚本完成之前,这不会显示回显。出了什么问题?

【问题讨论】:

标签: php


【解决方案1】:

您也可以尝试使用 ob_flush() 有时两者都需要。

【讨论】:

    【解决方案2】:

    来自 PHP 手册:

    flush() 可能无法覆盖 Web 服务器的缓冲方案,并且它对浏览器中的任何客户端缓冲都没有影响。它也不会影响 PHP 的用户空间输出缓冲机制。这意味着如果您正在使用 ob_flush() 和 flush() 来刷新 ob 输出缓冲区,则必须调用它们。

    echo "Hello!";
    flush();
    ob_flush();
    
    for($i = 0; $i < 10; $i ++) {
        echo $i;
        //5-10 sec execution time
        flush();
        ob_flush();
    }
    

    -或者-您可以刷新并关闭缓冲

    <?php
    //Flush (send) the output buffer and turn off output buffering
    while (ob_get_level() > 0)
        ob_end_flush();
    
    echo "Hello!";
    
    for($i = 0; $i < 10; $i ++) {
        echo $i . "\r\n";
    }
    
    ?>
    

    【讨论】:

      【解决方案3】:

      一般来说,使用纯 PHP 和 HTML 所希望的行为不可能是确定性/稳定的方式

      浏览器是否以及如何呈现部分页面取决于浏览器、代理和缓存。因此,即使这些东西在您的测试机器上工作,它也很可能在您的生产系统上不起作用。

      xAjax 提供了一个使用 PHP 管理 AJAX 样式更新的集成解决方案。虽然 xAjax 作为一个项目可能已经死了(至少现在是这样),但它仍然可以正常工作。

      【讨论】:

        【解决方案4】:

        试试这个

        while (@ob_end_flush());      
        ob_implicit_flush(true);
        
        echo "first line visible to the browser";
        echo str_pad("",1024," ");
        echo "<br />";
        
        sleep(5);
        
        echo "second line visible to the browser after 5 secs";
        

        请注意,这种方式实际上是在禁用当前脚本的输出缓冲区。因此,如果您在此之后尝试“ob_end_flush()”,您将收到没有要关闭的缓冲区的警告。

        【讨论】:

          【解决方案5】:

          确保你先这样做:

          @ini_set('zlib.output_compression', 0); @ini_set('implicit_flush', 1); @ob_end_clean();

          然后每次您需要将回声输出到浏览器时只需flush();

          【讨论】:

            【解决方案6】:

            还要确保首先输出 Content-type 标头。没有以下情况,冲洗对我不起作用:

            header( 'Content-type: text/html; charset=utf-8' );
            for($i=0; $i<10; ++$i)  {
                echo "Loop<br />\n";
                ob_flush();
                flush();
                sleep(1);
            }
            

            【讨论】:

              【解决方案7】:

              将此添加到脚本的标题

              ob_start();
              ob_implicit_flush();
              

              隐式刷新将导致在每次输出调用后进行刷新操作,因此不再需要对 flush() 的显式调用。 请注意,在脚本执行中添加隐式刷新会影响性能。您可以为脚本添加调试模式,例如:

              ob_start();
              define(DEBUG, 1);
              
              if(DEBUG){
                  ob_implicit_flush();
              }
              

              【讨论】:

                猜你喜欢
                • 2016-07-29
                • 1970-01-01
                • 1970-01-01
                • 2018-09-01
                • 2021-11-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多