Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Flush that works... even in Nginx

Tags:

php

nginx

flush

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.

like image 985
Roger Avatar asked Feb 02 '11 04:02

Roger


3 Answers

The easiest way to eliminate nginx's buffering is by emitting a header:

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

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

like image 184
Andy Fowler Avatar answered Sep 21 '22 12:09

Andy Fowler


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:

ob_implicit_flush(1);

for($i=0; $i<10; $i++){
    echo $i;

    //this is for the buffer achieve the minimum size in order to flush data
    echo str_repeat(' ',1024*64);

    sleep(1);
}

Related:

  • php flush not working

  • How to flush output after each `echo` call?

  • PHP flushing output as soon as you call echo

like image 30
Roger Avatar answered Sep 20 '22 12:09

Roger


Easy solution on nginx server:

fastcgi_keep_conn on; # < solution

proxy_buffering off;
gzip off;
like image 27
Ondrej Prochazka Avatar answered Sep 20 '22 12:09

Ondrej Prochazka