Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I'm running into issues with the PHP output buffer flushing on my Linux web server. The output buffer is maintained correctly and all the right data is pushed to it in my code, but the usual flushing mechanisms won't flush it to the browser. I have tried everything posted here: http://php.net/manual/en/function.flush.php but no success so far.

I got a small script from php.net to test it:

<?php
    ob_start();
    for($i=0;$i<70;$i++)
    {
        echo 'printing...<br />';
        ob_get_flush();
        flush();
        usleep(300000);
    }
?>

This should print "printing..." to the browser 70 times, one line every three seconds. This works fine on my other testing environment which is based on Windows (still using apache, XAMPP package), but on my Linux server it doesn't. It waits for the script to finish before giving anything to the browser, basically ignoring the whole flush command.

If anyone has experienced this before or knows of anything that could help (be it server configuration or adjustment to code) it would be greatly appreciated!

share|improve this question

3 Answers 3

I had this problem and found that the lines:

while ( @ob_end_flush() ); // even if there is no nested output buffer
flush();

would solve the problem.

Results may vary. This works on my system with IE and Apache 2.0.55.

Jeff

share|improve this answer
    
I spent three days looking at this issue and this is the only thing that worked for me. Now to figure out why it works... –  Joseph Erickson Oct 22 '11 at 13:59

Flushing PHP's output buffer and flushing Apache's buffer are two different tasks. It often happens that you flush PHP's output buffer but nothing is sent to the browser by Apache until there's more data. Also, sometimes the browser won't display anything until it receives enough data. What you can try is to "pad" your output with newlines.

There's two other issues with the code you posted. First, it starts output buffering once, and then ends it multiple times in the loop. You either want output buffering on inside the loop as well, or you might simply omit it. The other issue is, ob_get_flush() will return the contents of the output buffer as a string, not echo it.

Try this code instead:

<?php
    for($i=0;$i<70;$i++)
    {
        echo 'printing...<br />';
        echo str_repeat("\n",1024);
        flush();
        usleep(300000);
    }
?>

From the PHP Manual:

flush() may not be able to override the buffering scheme of your web server and it has no effect on any client-side buffering in the browser. [...]

Server modules for Apache like mod_gzip may do buffering of their own that will cause flush() to not result in data being sent immediately to the client.

Even the browser may buffer its input before displaying it. Netscape, for example, buffers text until it receives an end-of-line or the beginning of a tag, and it won't render tables until the tag of the outermost table is seen.

Some versions of Microsoft Internet Explorer will only start to display the page after they have received 256 bytes of output, so you may need to send extra whitespace before flushing to get those browsers to display the page.

My example attempts to work around this by sending 1024 newlines.

share|improve this answer
    
Thanks for the quick reply! I read somewhere that the buffer needs to be filled sometimes mainly due to IE requiring more data before it shows anything. I tried that now and before, but it has no effect on how my Linux server handles it. Doesn't seem to be a browser buffer size issue, since it works in the same way with whatever browser I try (IE6-8, Firefox, Chrome etc.) –  Iiro Vaahtojärvi May 3 '10 at 12:11
    
Oh yeah, I tried with the exact code you posted (without the flaws you pointed out). I also should mention that gzip compression of the buffer is not turned on in the php.ini, which to my understanding is pretty much unmodified from a fresh install - except from the script execution time length values. –  Iiro Vaahtojärvi May 3 '10 at 12:16
    
Are you using apache's mod_php or FastCGI PHP? –  Josh May 3 '10 at 14:54
    
mod_php is the one I'm using. Apparently the gzip compression is something that's just on by default and it doesn't have a specific setting to turn it off? I tried turning it off explicitly like here (php.net/manual/en/function.flush.php#87807), but still no help. –  Iiro Vaahtojärvi May 4 '10 at 6:08
    
@Josh - Perfect, thanks! –  MikeSchinkel Nov 23 '11 at 4:57

As noted in the PHP documentation, a common cause for this in my experience is output buffering by mod_gzip on Apache. Many distributions have this enabled by default now.

Mark

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.