PHP Flush that works... even in Nginx
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
Flush output buffer in Apache/Nginx setup
You should turn off buffering in nginx:
proxy_buffering off;
Reference: http://nginx.org/r/proxy_buffering
How to disable output buffering in nginx for PHP application
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');
php flush not working
You're using ob_flush
without ob_start
, so there is nothing to flush for it.
It also depends on the webserver and proxy and its settings.
You should disable buffering for Nginx (add proxy_buffering off;
to the config file and restart Nginx)
Also, check if your php.ini contains output_buffering = Off
and zlib.output_compression = Off
.
PHP flush don't work
This works, but only in a default apache environment:
<?php
ini_set('output_buffering', 0);
ini_set('zlib.output_compression', 0);
if( !ob_get_level() ){ ob_start(); }
else { ob_end_clean(); ob_start(); }
for ($i = 0; $i < 10; $i++) {
//For Nginx we have to reach minimum buffer size,
//so if it is not enough increment output
echo str_pad( $i . '<br>', 1024 + 10, ' ', STR_PAD_RIGHT );
flush();
ob_flush();
sleep(1);
}
Nginx needs more configurations:
usually in /etc/nginx/nginx.conf
gzip off;
proxy_buffering off;
fastcgi_buffer_size 1k; #set buffer to 1k
fastcgi_max_temp_file_size 0;
fastcgi_buffers 128 1k; #set max buffer size to 1k + 128*1k
How to flush output after each `echo` call?
Edit:
I was reading the comments on the manual page and came across a bug that states that ob_implicit_flush
does not work and the following is a workaround for it:
ob_end_flush();
# CODE THAT NEEDS IMMEDIATE FLUSHING
ob_start();
If this does not work then what may even be happening is that the client does not receive the packet from the server until the server has built up enough characters to send what it considers a packet worth sending.
Old Answer:
You could use ob_implicit_flush
which will tell output buffering to turn off buffering for a while:
ob_implicit_flush(true);
# CODE THAT NEEDS IMMEDIATE FLUSHING
ob_implicit_flush(false);
PHP flushing output as soon as you call echo
The script works fine from CLI, displaying "Fun", waiting 5 secs before displaying "<br>Mo".
For a browser the results might be a bit different because:
- The browser wont start rendering right away. Getting 3 bytes of data for HTML document isn't enough to do anything, so it'll most likely wait for a few more.
- Implicit IO buffering on the lib level will most likely be active until a newline is received.
To work around 1) use text/plain content type for your test; 2) needs newlines, so do an echo "Fun\n";
and echo "<br>Mo\n";
Of course you wont be using text/plain for real HTML data.
Related Topics
Adding Subscribers to a List Using Mailchimp's API V3
How to Use Class Methods as Callbacks
What Is the Format for E-Mail Headers That Display a Name Rather Than the E-Mail
Long Polling/Http Streaming General Questions
How to Call a Controller Function Inside a View in Laravel 5
Debug a Domdocument Object in PHP
Undefined Class Constant 'Mysql_Attr_Init_Command' with Pdo
How to Get All Captures of Subgroup Matches with Preg_Match_All()
Executing PHP Code Inside a .Js File
Do Ajax Requests Retain PHP Session Info
How to Get File Url Using Storage Facade in Laravel 5
PHP Function Use Variable from Outside
Algorithms for String Similarities (Better Than Levenshtein, and Similar_Text)? PHP, Js
Access a Global Variable in a PHP Function
Find Number Which Is Greater Than or Equal to N in an Array
Php: Check If Variable Exist But Also If Has a Value Equal to Something