20

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 to the way nginx works (by default).

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

6 Answers 6

38

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');
Sign up to request clarification or add additional context in comments.

6 Comments

just adding header('X-Accel-Buffering: no'); worked for me :)
header('X-Accel-Buffering: no'); worked for me, thank you sir for that, spent 2 hours googling and nothing worked only this
fastcgi_buffering off; in the nginx.conf worked for me, thanks!
Thanks! The header('X-Accel-Buffering: no'); worked for me, too!
header('X-Accel-Buffering: no'); worked for me. Thanks!
|
5

Easy solution:

fastcgi_keep_conn on; # < solution

proxy_buffering off;
gzip off;

4 Comments

Actually like you said, fastcgi_keep_conn on; was the secret word.
why isnt the fastcgi_keep_conn directive documented ?
where do these go?
You can use it in nginx http, server or location . nginx.org/en/docs/http/…
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.

1 Comment

Result for me: ERR_CONTENT_DECODING_FAILED
2

I needed both of those two lines at the beginning of my script:

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

Each line alone would also work, combining them makes my browser getting the result from the server even faster. Cannot explain it, just experienced it.

My configuration is nginx with php-fpm.

Comments

0

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!)

Comments

0

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.