Newest Industry

Evolving the Online Performance Experience

Compressing PHP Output

with 4 comments

A little-used or discussed feature of PHP is the ability to compress output from the scripts using GZIP for more efficient transfer to requesting clients. By automatically detecting the ability of the requesting clients to accept and interpret GZIP encoded HTML, PHP4 can decrease the size of files transferred to the client by 60% to 80%.

The information given here is known to work on systems running Red Hat 8.0, Apache/1.3.27, Apache/2.0.44 and PHP/4.3.1.

[Note: Although not re-tested since this article was originally written, compression is still present in the PHP 5.x releases and can be used to effectively compress content on shared or hosted servers where compression is not enabled within the Web server.]

Configuring PHP

The configuration needed to make this work is simple. Check your installed Red Hat RPMS for the following two packages:

  1. zlib
  2. zlib-devel

For those not familiar with zlib, it is a highly efficient, open-source compression library. This library is used by PHP uses to compress the output sent to the client.

Compile PHP4 with your favourite ./configure statement. I use the following:

Apache/1.3.27
./configure –without-mysql –with-apxs=/usr/local/apache/bin/apxs –with-zlib

Apache/2.0.44
./configure –without-mysql –with-apxs2=/usr/local/apache2/bin/apxs –with-zlib

After doing make && make install, PHP4 should be ready to go as a dynamic Apache module. Now, you have to make some modifications to the php.ini file. This is usually found in /usr/local/lib, but if it’s not there, don’t panic; you will find some php.ini* files in the directory where you unpacked PHP4. Simply copy one of those to /usr/local/lib and rename it php.ini.

Within php.ini, some modifications need to be made to switch on the GZIP compression detection and encoding. There are two methods to do this.


Method 1:

output_buffering = On
output_handler = ob_gzhandler
zlib.output_compression = Off


Method 2:

output_buffering = Off
output_handler =
zlib.output_compression = On


Once this is done, PHP4 will automatically detect if the requesting client accepts GZIP encoding, and will then buffer the output through the gzhandler function to dynamically compress the data sent to the client.

The ob_gzhandler

The most important component of this entire process is placing the ob_gzhandler PHP command on the page itself. It needs to be placed in the code at the top of the page, above the HTML tag in order to work. It takes the addition of the following line to complete the process:

<?php ob_start("ob_gzhandler"); ?>

In WordPress installs, this becomes the first line in the HEADER.PHP file. But be careful to check that it’s working properly. If the Web application has the compression function built into it, and you add the ob_gzhandler function, a funky error message will appear at the top of the page telling you that your can’t invoke compression twice.

Web servers with native compression are smarter than that – they realize that the file is already compressed and don’t run it through the compression algorithm again.

Once this is in place, you will be able to verify the decrease in size using any HTTP browser capture tool (Firebug, Safari Web Inspector, Fiddler2, etc.)

So?

The winning situation here is that for an expenditure of $0 (except your time) and a tiny bit more server overhead (you’re probably still using fewer resources than if you were running ASP on IIS!), you will now be sending much smaller, dynamically generated html documents to your clients, reducing your bandwidth usage and the amount of time it takes to download the files.

How much of a size reduction is achieved? Well, I ran a test on my Web server, using WGET to retrieve the file. The configuration and results of the test are listed below.

Method 0: No Compression
wget www.pierzchala.com/resume.php
File Size: 9415 bytes
Method 1: ob_gzhandler
wget –header=”Accept-Encoding: gzip,*” www.pierzchala.com/resume.php
File Size: 3529 bytes
Method 2: zlib.output_compression
wget –header=”Accept-Encoding: gzip,*” www.pierzchala.com/resume.php
File Size: 3584 bytes

You will have to experiment with the method that give the most efficient balance between file size and overhead and processing time on your server.

A 62% reduction in transferred file size without affecting the quality of the data sent to the client is a pretty good return for 10 minutes of work. I recommend including this procedure in all of your future PHP4 builds.

Advertisement

Written by Stephen

October 3 2006 at 16:20

Posted in Uncategorized

4 Responses

Subscribe to comments with RSS.

  1. Can you please let me know how much overhead it would be on my server. I've VPS plan with about 50 sites hosted.- Shobhithttp://shobhit.net/

    Shobhit Prabhakar

    February 12 2009 at 09:21

  2. It shouldn't affect you performance to any great degree as it is used in many production environments currently.However, if you do have the ability to do compression inside of the Web server itself (Apache, IIS, etc.), I would recommend that over adding compression at the application layer.smp

    Stephen Pierzchala

    February 16 2009 at 13:05

  3. It shouldn't affect you performance to any great degree as it is used in many production environments currently.However, if you do have the ability to do compression inside of the Web server itself (Apache, IIS, etc.), I would recommend that over adding compression at the application layer.smp

    Stephen Pierzchala

    February 16 2009 at 20:05

  4. Steph,
    Thanks for the post.
    Using zlib, I want to have content flushed at 3072 and compressed at level 4.

    For

    zlib.output_handler = On

    and

    implicit_flush = Off

    is this OK ?

    Many thanks, and good luck with consultancy business.

    radu

    output_buffering = Off
    output_handler =
    zlib.output_compression = 3072
    zlib.output_compression_level = 4
    zlib.output_handler = On
    implicit_flush = Off

    Radu

    January 9 2012 at 17:30


Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

Please log in to WordPress.com to post a comment to your blog.

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 269 other followers