How to disable output buffering in nginx for PHP a

2019-02-02 09:15发布

问题:

We have code similar to this:

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

    foreach ($arrayOfStrings as $string) {
        echo time_expensive_function($string);
    }
?>

In Apache, this would send each echo to the browser as it was output. In nginx/FastCGI however, this doesn't work due tot he way nginx works (by default).

Is it possible to make this work on nginx/FastCGI, and if so, how?

回答1:

None of the above solutions worked for me.

First php has to correctly flush everything :

@ob_end_flush();
@flush();

Then, I found two working solutions:

1) Via Nginx configuration:

fastcgi_buffering off;

2) Via HTTP header in the php code

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


回答2:

Easy solution:

fastcgi_keep_conn on; # < solution

proxy_buffering off;
gzip off;


回答3:

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:

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

Then do the flush as normal:

ob_end_flush();
flush();

Nginx seems to pick up on the encoding having been turned off and doesn't gzip.



回答4:

Add the flush() function in your loop:

foreach ($arrayOfStrings as $string) {
  echo time_expensive_function($string);
  flush();
}

It might work, but not necessarily on each iteration (there's some magic involved!)



回答5:

Add the -flush to the FastCGI config, refer to the manual:

  • http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiServer

  • http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiConfig

  • http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiExternalServer

From http://mailman.fastcgi.com/pipermail/fastcgi-developers/2009-July/000286.html