Question

I'm trying to have my page output it's < head > + some body stuff, and send it to the browser.

Then make some long mysql queries and output the rest of the page.

This works perfectly as long as I don't gzip the content.

Example:

A simplified example of the code I use which works:

<?php
ini_set('output_buffering', 'on');

echo "head..wait 3 secs</br>";
ob_flush();
flush();

sleep(3);
echo 'tail';
?>

See it live here but no gzip

or what I'm trying to get working:

<?php
ini_set('output_buffering', 'on');
ini_set('zlib.output_compression', 'On');

echo "head...wait 3 secs</br>";
ob_flush();
flush();

sleep(3);
echo 'bar';                     
?>

Which doesn't work see: here

I need this to work in my application but not on all pages (some don't need gzip or are libraries which handle it them selves, caldav library for example), so I prefer a php solution rather than enabling deflate application wide with .htaccess

What can I do to make flushing gzipped content work?

Was it helpful?

Solution

I can't tell if this is going to help with your problem since buffering problems can happen even if not using gzip (zlib).

Firstly it may be that apache has deflate module (mod_deflate or mod_gzip) loaded:
You can try to disable it for current script like this:

apache_setenv('no-gzip', 1);

Secondly it may be that browser is using internal buffer for response (around 1kB is common for IE, newer Firefox and WebKit browsers, but some browsers may have more or less).
That could be solved by echoing at least 1kb of blanks like this example:

echo str_repeat(' ', 1024);

Note that when using zlib, echoing 1kb of blanks (uncompressed) and flushing will not trigger these browsers to parse and render any content until ~1kb of compressed data is received.

Thirdly, if using sessions (either explicit in script or via php.ini session.auto_start) you need to close the session in order for output to be sent:

session_write_close();

I assume your problem is with browser buffer and zlib. You may need to create more than 1kb of compressed data for browser to render it.

-- I had tried myself to create flushing with zlib and believe me that is a lots of text to render just for the browser to start processing, at the end i had to echo an image file (which is already compressed) in order for it to work.

ini_set('output_buffering', 'On');
//ini_set('implicit_flush', 'On');
ini_set('zlib.output_compression', 'On'); // by default 4kB
//ini_set('zlib.output_compression_level', 1);

echo "head...wait 3 secs</br>\n";
echo str_repeat("\n ", 500); // this is enought to work fine without zlib
echo '<span style="display:none">';
readfile('path/to/an/image/file.png'); // around 8kB (4kB should be enough)
echo '</span>';
ob_flush();
flush();

sleep(3);
echo 'bar';
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top