How to prevent Output buffering in PHP Apache with mod_gzip / mod_deflate

By | May 13, 2023

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.

Category: PHP
About Silver Moon

A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected].

One Comment

How to prevent Output buffering in PHP Apache with mod_gzip / mod_deflate
  1. openid

    What? Don’t try and compress files like GIFs and PNGs for crying out loud – they’re already in a compressed format!

Leave a Reply

Your email address will not be published. Required fields are marked *