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?
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');
Easy solution:
fastcgi_keep_conn on; # < solution
proxy_buffering off;
gzip off;
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.
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!)
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