如何在nginx中为PHP应用程序禁用输出缓冲?

20

我们有类似于这样的代码:

<?php
    ob_implicit_flush(true);
    ob_end_flush();

    foreach ($arrayOfStrings as $string) {
        echo time_expensive_function($string);
    }
?>
在 Apache 中,每个 echo 输出都会直接发送给浏览器。然而,在 nginx/FastCGI 中,由于 nginx 的工作方式(默认情况下),这种方法不起作用。
是否有可能在 nginx/FastCGI 上实现这一点?如果可以,应该如何实现?
6个回答

35

首先,PHP必须正确地清除所有内容:

@ob_end_flush();
@flush();

然后,我找到了两种可行的解决方案:

1)通过Nginx配置:

fastcgi_buffering off;

2) 通过 PHP 代码中的 HTTP 标头

header('X-Accel-Buffering: no');

11
只需添加 header('X-Accel-Buffering: no'); 就可以了解决我的问题 :) - Ifnot
1
header('X-Accel-Buffering: no'); 对我有用,谢谢您,先生。我花了2个小时在谷歌上搜索,什么都没用,只有这个有效。 - aeroson
在我的nginx.conf中,fastcgi_buffering off; 对我很有用,谢谢! - Shean Hoxie
2
谢谢!header('X-Accel-Buffering: no'); 对我也起作用了! - Chris Haas
header('X-Accel-Buffering: no'); 对我有用。谢谢! - Riz
你是救星!添加 @ob_end_flush(); @flush(); 解决了问题。只改变头部没有解决问题。 - Vaibhavraj Roham

5
简单解决方案:
fastcgi_keep_conn on; # < solution

proxy_buffering off;
gzip off;

实际上,就像你所说的那样,“fastcgi_keep_conn on;”是秘密密码。 - Mohammad AbuShady
为什么fastcgi_keep_conn指令没有被记录文档? - Silver Moon
非常感谢!你救了我的一天。 - Jekis
1
这些应该放在哪里? - Typel
您可以在nginx http、server或location中使用它。http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_keep_conn - Ondrej Prochazka

3

我不想关闭整个服务器或整个目录的gzip压缩,只想在一些特定情况下为几个脚本禁用gzip压缩。

只需在任何输出之前添加以下内容:

header('Content-Encoding: none;');

然后像平常一样执行flush操作:

ob_end_flush();
flush();

Nginx似乎注意到编码被关闭并且不会gzip。


我的结果:ERR_CONTENT_DECODING_FAILED - Roemer

0
在你的循环中添加flush()函数:
foreach ($arrayOfStrings as $string) {
  echo time_expensive_function($string);
  flush();
}

这可能有效,但不一定在每次迭代中都适用(其中有些魔法涉及!)



0
我需要在我的脚本开头加上这两行代码:
header('X-Accel-Buffering: no');
ob_implicit_flush(true);

每行单独使用也可以,但将它们组合在一起可以让我的浏览器更快地从服务器获取结果。无法解释,只是亲身体验过。

我的配置是nginx和php-fpm。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接