Introduction
Got into this issue at work today, and had my eyes in the internet search for hours till I decided that no acceptable solution exists. And then ah! It happens to work, so here it is. :)
Background
What exactly does real-time updating mean?
Have you ever seen how PHP output is shown on the browser? No matter what length code or how many loops you put into, the browser always waits to get everything, every tiny thing from PHP output before showing it to the user. Now this isn't convenient, eh?
Let's take a scenario where you have to get 1000 records from a database and do very high time consuming calculations on each record. So under normal conditions, the user will be looking at a blank page for several minutes [or hours depending on your processor :D]. This isn't any fault of PHP, of course if you run PHP from the terminal (WAMP users don't look confused now), you'll see the output in realtime. So what's preventing it?
Buffering!
Using the Code
The Quick Solution
Just like every other problem, there's the easy short code to do this. It has been tested with Chrome and Firefox in a standard LAMP server without any server config changes.
Usual PHP output code is as given below:
echo "add this";
sleep(5);
echo "Program Output";
Output [the whole thing displays after 5 seconds]:
add thisProgram output
PHP with buffering off:
echo "add this";
echo str_pad("",1024," ");
echo " <br />"
ob_flush();
flush();
sleep(5);
echo "Program Output";
ob_flush();
flush();
Output [the whole thing displays after 5 seconds]:
add this
[waiting 5 seconds]
Program output
So let's talk about buffering. The feature-thingy that put the whole output at last is because there are several layers of buffering undergoing on the PHP output to make the output process efficient:
- by php : The
ob_*
functions are related to this, ob_flush() would stop/flush the buffer - by server : gzip compression,
output_buffering
in php5.ini does these - by client : Browsers like to do less work, so they wait for considerable amount of data to come before showing them to the user
Important Tweaks of the Code
-
echo str_pad("",1024," ");
As I mentioned, browsers do their own buffering to wait for some amount of data before showing content to user
- FF - 512 bytes
- chrome - 1024 bytes
- IE - why would you ask? :D
What the above code does is add 1024 blanks to the output, just to make it complete.
-
echo " <br />"
Even after the above tweak, I found that Chrome doesn't show the output as expected. After few more hours of trial and error [at the workplace], I found that it needs to read a newline before actually giving any output. Strange huh? So I simply added a HTML newline and VIOLA :D
Now the code seems to be working but only buffering (1) and (3) seem to be addressed. So let's make the code complete in case the server had some bad-ass buffering and caching going. But you won't need all of these, just do trial and error to find the best methods for you.
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);
while (@ob_end_flush());
ini_set('implicit_flush', true);
ob_implicit_flush(true);
echo "add this";
echo str_pad("",1024," ");
echo "<br />";
ob_flush();
flush();
sleep(5);
echo "Program Output";
ob_flush();
flush();
References
- ob_flush()
- flush()