Till recently most of my php scripts were working fine on the servers with instantaneous outputs as and when a echo statement was encountered.
Output in Chunks
One issue that popped a lot on localhost was that of chunky outputs; that is the outputs of big scripts came out in chunks rather than smoothly with every echo or print statement.
Flushing on demand
After some research flush()
was found to be the solution for this output buffering issue. So what happened was that php was buffering the output and giving it out in good-sized chunks.
echo $large_data; flush();
Note that if you used php's internal buffering mechanism using ob_start, then you need to call ob_flush first before calling final flush.
ob_start(); echo $large_data; ob_flush(); flush();
This discussion at stackoverflow explaining the difference of flush and ob_flush.
Buffering at HTTP Server Level
PHP may not be the only place where the output gets buffered. Between PHP and the browser lies the http web server like Apache which can buffer the output. Enabling mod_deflate/mod_gzip can lead to output buffering.
Many cPanel based hosting servers have a configuration option called "Optimise Website" option where users can select the file types on which compression is to be applied.
Enabling that options enables mod_gzip or mod_deflate which then compresses all output before being send to the browser. Now this compression may lead to some amount of buffering and then any calls to flush() or ob_flush() inside php shall appear to have NO Effect since apache will now buffer the output.
So a better option is to selectively compress mime types. When outputting large amounts of data in real time, use a specific mime-type and configure the http server to not compress that particular mime-type.
The following is the recommended mime-type for sending raw data that can be skipped for compression of any type.
application/octet-stream
Mime types to compress can be specified in the "Optimise Website" section of cPanel. To compress only javascript, css , gifs and pngs and flash files the following mime-types can be marked:
- application/x-javascript
- text/css
- text/xml
- image/png
- image/gif
- text/javascript
- application/x-shockwave-flash
- text/html
- text/plain
Just keep out the application/octet-stream
mime type from compression or optimisation of any kind.
On php side any data that need to be outputted in realtime should be preceded by a content type header indicating application/octet-stream
. This will keep the output of php files smooth and prevent buffering or the chunky output scenario.
Compressing inside PHP
There are other more exotic techniques like compressing stuff entirely inside php and keeping the web-server in a simple mode. This can be done with the function ob_start("ob_gzhandler")
.
So for example you want to compress a css files style.css, then rename it to style.css.php and then employ some php code to do the compression magic.
style.css.php
<?php ob_start("ob_gzhandler"); ?> ... CSS CODE
This same technique can be used for .js javascript files, .html html files and other files generating text based content.That php code compresses all output that follows in the script.
Check the ob_gzhandler documentation to learn more.
But this technique isnt good to be used with non-text files like images flash animations etc.
What? Don’t try and compress files like GIFs and PNGs for crying out loud – they’re already in a compressed format!