windows 调用 echo 后,PHP 会立即刷新输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3483035/
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-09-15 15:02:33  来源:igfitidea点击:

PHP flushing output as soon as you call echo

phpwindowsflush

提问by Luca Matteis

I thought flush();would work, at least from what Google/Stackoverflow tell me, but on my Windows WAMP (Windows, Apache, MySQL, PHP) system it doesn't work.

我认为flush();会起作用,至少从 Google/Stackoverflow 告诉我的情况来看,但在我的 Windows WAMP(Windows、Apache、MySQL、PHP)系统上它不起作用。

Is there some PHP setting I have to set to make flush() work?

是否有一些 PHP 设置我必须设置才能使flush() 工作?

Here's my code:

这是我的代码:

<?php
echo "Fun";

flush();

sleep(5);

echo "<br>Mo";
?>

The code just outputs all together when the script is done executing (after 5 seconds).. I don't want this, I want 'Fun' to show up right away, and then after 5 seconds 'Mo'.

当脚本完成执行时(5 秒后),代码只是一起输出。我不希望这样,我希望“Fun”立即显示,然后在 5 秒后显示“Mo”。

I've tried other combinations of flush like ob_end_flush();or ob_implicit_flush(true);but nothing is working. Any ideas?

我尝试过其他的冲洗组合,ob_end_flush();or ob_implicit_flush(true);但没有任何效果。有任何想法吗?

回答by Roger

So that's what I found out:

所以这就是我发现的:

Flush would not work under Apache's mod_gzip or Nginx's gzip because, logically, it is gzipping the content, and to do that it must buffer content to gzip it. Any sort of web server gzipping would affect this. In short, at the server side, we need to disable gzip and decrease the fastcgi buffer size. So:

Flush 不能在 Apache 的 mod_gzip 或 Nginx 的 gzip 下工作,因为从逻辑上讲,它正在对内容进行 gzip,为此它必须缓冲内容以对其进行 gzip。任何类型的 Web 服务器 gzipping 都会影响这一点。简而言之,在服务器端,我们需要禁用 gzip 并减小 fastcgi 缓冲区大小。所以:

  • In php.ini:

    . output_buffering = Off

    . zlib.output_compression = Off

  • In nginx.conf:

    . gzip off;

    . proxy_buffering off;

  • 在 php.ini 中:

    . 输出缓冲 = 关

    . zlib.output_compression = 关

  • 在 nginx.conf 中:

    . gzip 关闭;

    . 代理缓冲关闭;

Also have this lines at hand, specially if you don't have acces to php.ini:

手头也有这些行,特别是如果您没有访问 php.ini 的权限:

  • @ini_set('zlib.output_compression',0);

  • @ini_set('implicit_flush',1);

  • @ob_end_clean();

  • set_time_limit(0);

  • @ini_set('zlib.output_compression',0);

  • @ini_set('implicit_flush',1);

  • @ob_end_clean();

  • 设置时间限制(0);

Last, if you have it, coment the code bellow:

最后,如果你有的话,评论下面的代码:

  • ob_start('ob_gzhandler');

  • ob_flush();

  • ob_start('ob_gzhandler');

  • ob_flush();

PHP test code:

PHP测试代码:

ob_implicit_flush(1);

for($i=0; $i<10; $i++){
    echo $i;

    //this is for the buffer achieve the minimum size in order to flush data
    echo str_repeat(' ',1024*64);

    sleep(1);
}

回答by jmz

The script works fine from CLI, displaying "Fun", waiting 5 secs before displaying "<br>Mo".

该脚本在 CLI 中运行良好,显示“Fun”,等待 5 秒后显示“<br>Mo”。

For a browser the results might be a bit different because:

对于浏览器,结果可能会有所不同,因为:

  1. The browser wont start rendering right away. Getting 3 bytes of data for HTML document isn't enough to do anything, so it'll most likely wait for a few more.
  2. Implicit IO buffering on the lib level will most likely be active until a newline is received.
  1. 浏览器不会立即开始渲染。为 HTML 文档获取 3 个字节的数据还不足以做任何事情,所以它很可能会等待更多。
  2. 在接收到换行符之前,lib 级别的隐式 IO 缓冲很可能处于活动状态。

To work around 1) use text/plain content type for your test; 2) needs newlines, so do an echo "Fun\n";and echo "<br>Mo\n";Of course you wont be using text/plain for real HTML data.

解决方法 1) 使用文本/纯内容类型进行测试;2) 需要换行符,所以做一个echo "Fun\n";andecho "<br>Mo\n";当然你不会使用 text/plain 来处理真正的 HTML 数据。

回答by Vincent

If you're using CGI/FastCGI, forget it! These don't implement flush. The Webserver might have it's own buffer.

如果您使用的是 CGI/FastCGI,请忘记它!这些不实现刷新。Web 服务器可能有自己的缓冲区。

You can disable all output buffering in PHP with following command:

您可以使用以下命令禁用 PHP 中的所有输出缓冲:

ob_implicit_flush();

回答by Philipp

If the problem persists, although you explicitly set

如果问题仍然存在,尽管您明确设置

implicit_flush = yes 

in your php.ini, you might also want to set

在您的 php.ini 中,您可能还想设置

output_buffering = off

which did the trick in my case (after pulling my hair for 4+hrs)

这在我的情况下起到了作用(拉我的头发 4 个多小时后)

回答by tamasd

Check your php.ini for output_buffering.

检查您的 php.ini 中的output_buffering.

回答by Savageman

Maybe the problem is Apache here, which also may have buffers...

也许问题是这里的Apache,它也可能有缓冲区......