Currently Browsing: Home » GZip files with .htaccess and PHP

GZip files with .htaccess and PHP

Many hosts have a set bandwidth clients can use. In this day and age, files are getting larger and heavier, but bandwidth costs aren’t getting much cheaper. So, one of the best and easiest things to do is to GZip.

From “The Definitive Post on GZipping your CSS

CSS files for larger sites can become pretty large themselves. Gzipping or compressing these files has shown to provide a reduction in the neighborhood of 70-80% of the original file size, a fairly significant ‘weight loss’.

So obviously, GZipping CSS is great. But what about JS? JavaScript files are becoming increasingly huge, so what should we do about that?

The article from Fiftyfoureleven that is linked to suggests using the following PHP snippet:

<?php
    ob_start ("ob_gzhandler");
    header("Content-type: text/css; charset: UTF-8");
    header("Cache-Control: must-revalidate");
    $offset = 60 * 60 ;
    $ExpStr = "Expires: " .
    gmdate("D, d M Y H:i:s",
    time() + $offset) . " GMT";
    header($ExpStr);
?>

and then the following .htaccess snippet:

AddHandler application/x-httpd-php .css
php_value auto_prepend_file gzip-css.php
php_flag zlib.output_compression On

So then the obvious solution for JS files would be to make a file called gzip-js.php, with the same PHP snippet with the content type modified to text/javascript, like the one seen at Perishable Press.

Then we run into a problem. For systems like WordPress or ExpressionEngine or Habari, where css or js files might be sent from many different folders, manually putting the .htaccess and gzip file may not be convenient, so I created this system.

gzip.php:

<?php
if(isset($_SERVER['HTTP_ACCEPT_ENCODING']) && substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))
ob_start('ob_gzhandler');
else
ob_start();
?>

.htaccess:

################ Expires Control ################
ExpiresActive On
ExpiresDefault A0
<FilesMatch "\.(gif|jpg|jpeg|png|swf)$">
# 2 weeks
ExpiresDefault A1209600
Header append Cache-Control "public"
</FilesMatch>
<FilesMatch "\.(xml|txt|html)$">
# 2 hours
ExpiresDefault A7200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>
<FilesMatch "\.(js|css)$">
# 3 days
ExpiresDefault A259200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>

################## GZip Files ###################
<FilesMatch "\.js$">
AddHandler application/x-httpd-php .js
php_value default_mimetype "text/javascript"
</FilesMatch>
<FilesMatch "\.css$">
AddHandler application/x-httpd-php .css
php_value default_mimetype "text/css"
</FilesMatch>
<FilesMatch "\.(htm|html|shtml)$">
AddHandler application/x-httpd-php .html
php_value default_mimetype "text/html"
</FilesMatch>
php_value auto_prepend_file /absolute/path/to/gzip.php

This snippet allows me to control the expires and content type using htaccess instead of PHP, like in the other examples. And because I use the absolute path to gzip.php, I can ensure that GZip gets applied to all php, js, css, html, shtml, and htm files.

Sources

This entry was posted on Sunday, December 21st, 2008 at 07:13:07. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

Want to be notified when someone replies? Subscribe to this post's comment RSS feed.
Any field marked with a * is required.