【问题标题】:PHP Flush() not working in ChromePHP Flush() 在 Chrome 中不起作用
【发布时间】:2011-08-25 11:45:11
【问题描述】:

我偶然发现了这个承诺可以跨 IE、FF 和 Chrome 运行的功能。但它在 Chrome 中不起作用。有解决办法吗?

function buffer_flush(){

    echo str_pad('', 512);
    echo '<!-- -->';

    if(ob_get_length()){

        @ob_flush();
        @flush();
        @ob_end_flush();

    }

    @ob_start();
}

【问题讨论】:

  • 首先删除那些@s,如果出现问题,你会得到更好的错误消息。此外,“它不起作用”从不是一个好的错误描述。你希望你的代码做什么,而不是做什么?这也可能是一个缓存问题。
  • 试过了,结果没有变化...
  • 不,删除@s 不会改变结果(你知道他们做什么,不是吗?如果不知道,你为什么一开始就把他们放进去?)。同样,您希望您的代码做什么以及它会做什么?这也可能是一个缓存问题。
  • 我只想在脚本执行时间歇性地回显文本。我确实知道 @ 的用途,但在这种情况下,我肯定不会期待任何错误。
  • 如果您没有预料到任何错误,为什么需要@s?

标签: php google-chrome buffer flush


【解决方案1】:

以下是我在 Chrome 12.0.742.122 和 PHP 5.3.6 中如何让 flush() 在 while 循环中工作:

echo("<html><body>");
while(1) {
  echo(str_pad($my_string_var,2048," "));
  @ob_flush();
  flush();
}

使用较小的 str_pad 值也可以,但是第一个输出出现需要更长的时间。如果缺少任何其他行,则不会出现任何内容。

“@”不是绝对必要的,但它可以防止日志被“缓冲区中没有任何内容”的通知填满。

当然,如果您有一个预先存在的页面,只需确保其中有 &lt;html&gt;&lt;body&gt; 标签即可;我正在从头开始写一个页面。

【讨论】:

    【解决方案2】:

    使用flush()/ob_flush(),您只需将输出发送到浏览器,但在显示时仍取决于浏览器。我假设,chrome 只是等待,直到它收到足够的数据来显示“有用”的页面,而不是一些片段。

    还是有一些建议:

    • 避免使用@(尤其是如果您不知道确切的用途)
    • 如果您不拨打ob_end_*(),则无需再次拨打ob_start()。效率低下

      function buffer_flush(){
        echo '<!-- -->'; // ?
      
        ob_flush();
        flush();
      }
      

    【讨论】:

    • 补充一点:如果您输出的唯一内容是 HTML 注释,您将看不到任何内容。如果我尝试输出视觉效果,我会在刷新时看到这个。
    • @Marcel:是的,当然。我总是看源代码,所以我错过了重点,很多人忘记了 html-cmets 不会显示在浏览器窗口中;)
    • 对我来说,诀窍是在 flush() 旁边使用 ob_flush()
    【解决方案3】:

    某些浏览器(至少是 IE6,可能还有 chrome)在输出任何内容之前需要一定数量的“有用”字符(即不是空格)。在IE6的情况下,甚至需要推送压缩数据的大小。

    function force_flush() {
        echo "\n\n<!-- Deal with browser-related buffering by sending some incompressible strings -->\n\n";
    
        for ( $i = 0; $i < 5; $i++ )
            echo "<!-- abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono -->\n\n";
    
        while ( ob_get_level() )
            ob_end_flush();
    
        @ob_flush();
        @flush();
    } # force_flush()
    

    【讨论】:

      【解决方案4】:

      有几个组件可能会对这个问题产生影响。

      仔细阅读这个函数的文档: http://www.php.net/manual/en/function.flush.php

      我的一个解决方案是将 Apache2 与 mod-php(不是 fcgi,而是作为本机 apache 模块)和 Chromium 一起使用。结果立即出现,脚本仍在运行并发送更多结果。

      在输入以下两行代码后,每个 echo-command 都会立即将文本推送到 whatever-PHP-backend

      ob_implicit_flush(1);
      @ob_end_flush(); // set an end to the php-output-buffer!
      

      但是这个 php 后端可以有自己的缓冲区。例如,我将 nginx 作为网络服务器运行,而 fast-cgi 模块使用 php。 Nginx 本身有自己的缓冲区……等等。

      浏览器也可以缓冲请求。但根据我的经验,Chromium(或 Google Chrome)的缓冲区非常小或没有。

      请阅读我提到的每个函数的文档以了解它们的真正作用 - 特别是 flush() 的文档。

      个人提示:不要将多余的字符放入输出缓冲区,而是阅读并理解您的服务器的配置。

      编辑: 如果您启用了 gzip,来自服务器的整个响应将被缓冲。

      【讨论】:

      • “如果您启用了 gzip,来自服务器的整个响应将被缓冲”引导我 here.
      【解决方案5】:

      经过几次尝试和错误,我发现内容类型标头确实可以在 chrome 中使用。

      但我不知道为什么 chrome 不刷新。

      在搜索更多答案后,我读到只有当设置了有效的内容类型时,chrome 才会按预期刷新。很好。

      这是我实验的代码。

      <?php
      header('Content-Type: text/html; charset=UTF-8');
      
      echo 'starting...';
      flush();
      echo 'to sleep...';
      flush();
      sleep(5);
      echo 'awake';
      

      如果我不包含内容类型标头,我会在 5 秒后一口气得到如下内容。所以我们所期望的没有奏效。

      starting...to sleep...awake 显示,脚本终止。

      当我给上面的内容类型加上子类型(字符集)然后

      starting...to sleep... 立即显示,然后在 5 秒后显示 awake。

      我只是盲目地假设关于内容类型标题 chrome 显示了输出。

      除了我给出“Content-Type:text/plain”或“Content-Type:text/html”时,它不起作用。它仅适用于子类型 'charset=[sometexthere]'。

      就像 application/json 一样工作。而且我没有尝试更多的哑剧。

      我在这里的原因是

      我想在 ajax 响应中使用 readystate 3。除了 chrome 和 safari 外,它工作正常。因为 chrome 使用的是 webkit,所以我认为两者都是一样的。

      在包括 IE 在内的其他浏览器中,刷新按预期工作,并且 readystate=3,但在 chrome 和 safari 中,我只是使用了上述解决方法。

      这是上面 php 脚本中的 readystate - responsetext 的截图

      在图像中有两组响应,第一组的就绪状态为 3,当不使用内容类型时,responsetext 为空。

      在第二个响应中,您可以看到就绪状态 3 具有带有预期输出的响应文本。这是使用内容类型的时候。

      所以...只有 Chrome 知道。

      使用 str_pad 时

      当您使用字符串填充时,您可以获得更多预期的结果。我尝试使用上述答案建议的 1024,但仅设置了内容类型。

      如果使用了填充并且没有设置内容类型,那么它就不起作用。

      我提出了与此类似的question,我将通过将此答案链接到该答案并背靠背来添加我自己的答案......这样用户就可以轻松获得更多详细信息。嗯嗯。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-03
        • 2011-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多