PHP Flush 可以工作......甚至在 Nginx 中
是否可以在每次执行循环时回显?例如:
foreach(range(1,9) as $n){
echo $n."\n";
sleep(1);
}
我希望看到它每次打印每个结果,而不是在循环完成时打印所有内容。
Is it possible to echo each time the loop is executed? For example:
foreach(range(1,9) as $n){
echo $n."\n";
sleep(1);
}
Instead of printing everything when the loop is finished, I'd like to see it printing each result per time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
消除 nginx 缓冲的最简单方法是发出标头:
这会消除
proxy_buffering
和(如果您的 nginx >= 1.5.6)fastcgi_buffering
。如果您使用 php-fpm,fastcgi 位至关重要。根据需要进行标头也更加方便。有关 X-Accel-Buffering 的文档
有关 fastcgi_buffering 的文档
The easiest way to eliminate nginx's buffering is by emitting a header:
This eliminates both
proxy_buffering
and (if you have nginx >= 1.5.6),fastcgi_buffering
. The fastcgi bit is crucial if you're using php-fpm. The header is also far more convenient to do on an as-needed basis.Docs on X-Accel-Buffering
Docs on fastcgi_buffering
最终解决方案
这就是我发现的:
Flush 在 Apache 的 mod_gzip 或 Nginx 的 gzip 下不起作用,因为从逻辑上讲,它正在对内容进行 gzip 压缩,并且要做到这一点,它必须缓冲内容以对其进行 gzip。任何类型的 Web 服务器 gzip 压缩都会影响这一点。简而言之,在服务器端,我们需要禁用 gzip 并减小 fastcgi 缓冲区大小。所以:
在 php.ini 中:
。输出缓冲 = 关闭
。 zlib.output_compression = Off
在 nginx.conf 中:
。 gzip 关闭;
。 proxy_buffering off;
另外,请准备好以下几行,特别是如果您无法访问 php.ini:
@ini_set('zlib.output_compression',0);
@ini_set('implicit_flush',1);
@ob_end_clean();
set_time_limit(0);
最后,如果你有的话,注释下面的代码:
ob_start('ob_gzhandler');
ob_flush();
PHP 测试代码:
相关:
php 刷新不起作用
< a href="https://stackoverflow.com/questions/3133209/how-to-flush-output-after-each-echo-call/4763130#4763130">如何在每次“echo”调用后刷新输出?
一旦调用 echo,PHP 就会刷新输出
FINAL SOLUTION
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:
In php.ini:
. output_buffering = Off
. zlib.output_compression = Off
In nginx.conf:
. gzip off;
. proxy_buffering off;
Also have this lines at hand, specially if you don't have acces to php.ini:
@ini_set('zlib.output_compression',0);
@ini_set('implicit_flush',1);
@ob_end_clean();
set_time_limit(0);
Last, if you have it, coment the code bellow:
ob_start('ob_gzhandler');
ob_flush();
PHP test code:
Related:
php flush not working
How to flush output after each `echo` call?
PHP flushing output as soon as you call echo
nginx 服务器上的简单解决方案:
Easy solution on nginx server:
我不想在某些特定情况下为整个服务器或整个目录关闭 gzip,而只是为了一些脚本。
在任何内容被回显之前,你所需要的就是这个:
然后像平常一样进行刷新:
Nginx 似乎发现编码已被关闭,并且不进行 gzip。
I didn't want to have to turn off gzip for the whole server or a whole directory, just for a few scripts, in a few specific cases.
All you need is this before anything is echo'ed:
Then do the flush as normal:
Nginx seems to pick up on the encoding having been turned off and doesn't gzip.
您需要将 php 的缓冲区刷新到浏览器
请参阅: http://php.net/manual /en/function.flush.php
You need to flush the php's buffer to the browser
See: http://php.net/manual/en/function.flush.php
我发现您可以
在 php 脚本中设置:禁用 nginx gzipping,而无需修改
nginx.conf
I found that you can set:
in your php script to disable nginx gzipping without having to modify the
nginx.conf
您可以通过在循环中间刷新输出缓冲区来实现此目的。
示例:
请注意,如果您打开了 zlib 压缩,您的 php.ini 设置可能会影响此功能是否有效
You can accomplish this by flushing the output buffer in the middle of the loop.
Example:
Note that your php.ini settings can affect whether this will work or not if you have zlib compression turned on
我的 php-fpm 引擎遇到了 gzip 问题。
这段代码是唯一适合我的代码:
这是我的测试函数:它检查 max_execution_time :
I had a gzip problem comming from my php-fpm engine.
this code is the only one working for me :
This is my test function : it checks max_execution_time :
将 PHP Flush/Streaming 与 gzip 相结合(AWS ALB,仅限 nginx)
我对 PHP 流支持的兴趣是使浏览器能够尽早获取/重要资产,以最大限度地减少关键渲染路径。必须在 PHP 流式传输或 gzip 之间进行选择并不是真正的选择。过去,这在 Apache 2.2.x 中是可以实现的,但是当前版本似乎没有这样做。
我能够使用 PHP 7.4 和 Amazon Linux 2 (v3.3.x) 使其与 AWS Application Load Balancer 后面的 nginx 配合使用。并不是说它只适用于 AWS 堆栈,但是位于 nginx 前面的 ALB 改变了一些事情,我没有机会使用直接公开的实例来测试它。所以请记住这一点。
nginx
gzip_proxies & gzip_vary 是 gzipped 流的关键参数,tcp_ 参数用于禁用 nginx 缓冲/等待 200 毫秒(不确定这是否仍然是默认的 nginx 设置)。
就我而言,我只需要为 php 文件启用它,您应该能够将其移至服务器配置的更高位置。
php.ini
如果你想手动控制缓冲区何时发送到服务器/浏览器,请设置implicit_flush = Off并使用ob_flush(); lush() 和最后 ob_end_flush()。
Combining PHP Flush/Streaming with gzip (AWS ALB, nginx only)
My interest in PHP streaming support was to enable the browsers to fetch early/important assets early as to minimize the critical render path. Having to choose between either PHP streaming or gzip wasn't really an alternative. This used to be possible with Apache 2.2.x in the past, however it doesn't look like this is something that's being worked on for current versions.
I was able to get it to work with nginx behind an AWS Application Load Balancer using PHP 7.4 and Amazon Linux 2 (v3.3.x). Not saying it only works with the AWS stack, however the ALB sitting in front of nginx changes things and I didn't have a chance to test it with a directly exposed instance. So keep this in mind.
nginx
gzip_proxies & gzip_vary are the key parameters for gzipped streaming, the tcp_ parameters are to disable nginx buffering/waiting for 200ms (not sure if that's still a default nginx setting).
In my case I only needed to enable it for the php files, you should be able to move it higher into your server config.
php.ini
If you want to manually control when the buffer is sent to the server/browser, set implicit_flush = Off and use ob_flush(); flush() and finally ob_end_flush().