PHP Flush() 在 Chrome 中不起作用

发布于 2024-11-06 20:42:05 字数 292 浏览 4 评论 0原文

我偶然发现了这个函数,它承诺可以在 IE、FF 和 IE 上工作。铬合金。但它在 Chrome 中不起作用。有解决办法吗?

function buffer_flush(){

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

    if(ob_get_length()){

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

    }

    @ob_start();
}

I stumbled upon this function which promised to work across IE, FF & Chrome. But it does not work in Chrome. Is there a work around?

function buffer_flush(){

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

    if(ob_get_length()){

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

    }

    @ob_start();
}

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

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

发布评论

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

评论(5

陌路黄昏 2024-11-13 20:42:06

以下是我如何使用 PHP 5.3.6 在 Chrome 12.0.742.122 中的 while 循环中使用 flash() :

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

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

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

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

Here's how I got flush() working in a while loop in Chrome 12.0.742.122 with PHP 5.3.6:

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

Using a lesser str_pad value worked too, but it would take a bit longer for the first output to appear. If any of the other lines were missing, nothing would appear.

The "@" isn't strictly necessary, but it prevents the log from filling up with "nothing in the buffer" notices.

And of course if you have a pre-existing page, just make sure the <html> and <body> tags are in there; I was writing a page from scratch.

请你别敷衍 2024-11-13 20:42:06

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

无论如何,一些建议:

  • 避免使用 @ (特别是如果您不确切知道它的作用)
  • 如果您不调用 ob_end_*(),您不需要再次调用ob_start()。效率低下

    函数 buffer_flush(){
      echo ''; // ?
    
      ob_flush();
      冲洗();
    }
    

With flush()/ob_flush() you only send the output to the browser, but its still up to the browser, when it displays it. I assume, that chrome just waits, until it has enough data received to display a "useful" page, instead of some fragments.

Some suggestions anyway:

  • Avoid using @ (especially if you don't know exactly, what it does)
  • If you don't call ob_end_*(), you don't need to call ob_start() again. Its inefficient

    function buffer_flush(){
      echo '<!-- -->'; // ?
    
      ob_flush();
      flush();
    }
    
篱下浅笙歌 2024-11-13 20:42:06

某些浏览器(至少是 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()

Some browsers (IE6 at the very least, and possibly chrome) require a certain amount of "useful" characters (i.e. not spaces) before outputting anything. In the case of IE6, it even is the compressed data's size that needs to be pushed.

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()
我恋#小黄人 2024-11-13 20:42:06

有几个组件可能会影响此问题。

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

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

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

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

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

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

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

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

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

There are several components that can have impact on this issue.

Read carefully through the documentation of this function:
http://www.php.net/manual/en/function.flush.php

One solution I had was using Apache2 with mod-php (not as fcgi but as native apache-module) and Chromium. The result came immediately and the script was still running and sending more results.

After typing the following two code-lines every echo-command will immediately push the text to the whatever-PHP-backend:

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

But this php backend can have its own buffer. For example I run nginx as webserver and php is used by the fast-cgi module. Nginx itself has its own buffer ... and so on.

The Browser also can buffer the request. But as I experience Chromium (or Google Chrome) has a verry small or no buffer.

Please read the documentation of every function I mentioned to understand what they really do - but specially the documentation of flush().

Personal hint: Do not put extra characters into the output-buffer but read and understand the configuration of your server.

EDIT:
If you have gzip enabled the whole response from the server will be buffered.

羞稚 2024-11-13 20:42:06

经过几次尝试和错误后,我发现内容类型标头确实可以在 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 并且脚本终止。

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

开始...睡眠...时立即显示,然后在 5 秒后显示唤醒。

我只是盲目地假设关于内容类型标题,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 脚本中的就绪状态 - 响应文本

在此处输入图像描述

的屏幕截图,图像中有两组当不使用内容类型时,以就绪状态 3 响应第一个,响应文本为空。

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

所以...只有 Chrome 知道。

当使用 str_pad

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

如果使用填充并且未设置内容类型,则它不起作用。

并且

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

I found that a content type header really makes it work in chrome after few trial and errors.

But i don't know why chrome does not flush otherwise.

after searching for more answers i read that chrome flushes as you expect only when a valid content type is set. fine.

Here is the code i experimented.

<?php
header('Content-Type: text/html; charset=UTF-8');

echo 'starting...';
flush();
echo 'to sleep...';
flush();
sleep(5);
echo 'awake';

if i do not include the content type header i get like the following in one shot after 5 seconds. so what we expect did not work.

starting...to sleep...awake is displayed and the script terminates.

where as when i gave the content type like the above with the subtype(charset) then

starting...to sleep... is displayed immediately and then after 5 seconds awake is displayed.

i am just blindly assuming that with respect to the content type header chrome shows the output.

Besides when i gave 'Content-Type: text/plain' or 'Content-Type: text/html' it did not work. it worked only with the subtype 'charset=[sometexthere]'.

were as application/json worked. and i did not experiment with more mimes.

The reason i am here is

i wanted to use readystate 3 in ajax response. it works fine except chrome and safari. since chrome is using webkit it is the same in both i think.

in other browsers including IE the flushing is working as expected and also the readystate=3 but in chrome and safari i just used the above workaround.

here is the screenshot of the readystate - responsetext from the above php script

enter image description here

in the image there a two sets of response the first one with readystate 3 and responsetext as empty when content type is not used.

in the second response you can see ready state 3 has responsetext with the expected output. this is when content type is used.

so... Chrome only knows.

when used str_pad

When you use string padding you can get more expected result. i tried with 1024 as the above answers suggested but only with content type set.

if padding is used and no content type is set then it did not work.

and

i had raised a question similar to this and i am going to add my own answer by linking this answer to that and back to back... so that it will be easy for users to get more details. hhmmm.

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