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.

20 Responses to “GZip files with .htaccess and PHP”

  1. Diogo Shaw says:

    nice post…

    another simple way using htaccess:

    htaccess code:
    SetOutputFilter DEFLATE
    Header unset ETag
    FileETag None

    Diogo Shaw

  2. Thanks a million. That was the last piece of code to make my site get an A at yslow

  3. Arthur says:

    I am really fond of this idea, it can be applied to js as well, and to top it off you can automatically minify your css/js using a script like this, but I notice on your site the css files are coming in as gzipped (200) but they’re not caching (Says the mythical firebug 1.4). Is my firebug lying to me?

  4. Mitko says:

    My theme .css is not gzipping as well as some other files, any idea why this is happening?

    Everything else seems alright, but just these few css + js files!

  5. Navjot Singh says:

    I get a 500 Error when I use your method. Any ideas why?

  6. Torben says:

    Thanks go to Diogo from comment #1. The following works very well for me when put into htaccess (Hosteurope Webpack):

    SetOutputFilter DEFLATE
    Header unset ETag
    FileETag None

    Thanks,
    Torben

  7. FrankBongo says:

    Thanks very much. It too only worked for me when I put

    SetOutputFilter DEFLATE
    Header unset ETag
    FileETag None

    into .htaccess

    I also notice that this page isn’t using the compression, why is that?

  8. wcasado says:

    Thanks a million!!

    Implemented the Diogo post as:

    SetOutputFilter DEFLATE
    Header unset ETag
    FileETag None

    And this is all you really need….Also implemented the Expires Control which shows this article and they work just fine. Thanks for sharing!!!

    wcasado

  9. rozario says:

    This method will not work if your server has PHP installed as CGI binary – you will get a 500 internal server error.

  1. Article: GZip files with .htaccess and PHP :: Flow of Logic
  2. [Web] 連結分享 « 網站製作學習誌
  3. 4 Ways to Decrease Page Loading Time
  4. PHP动态生成CSS/JS 附中文使用 – 小V的天空
  5. 胡说九道 » 000webhost开启Gzip.
  6. Enable Gzip on Share Hosting: solution for plugin collision
  7. 20 Steps to a Flexible and Secure WordPress Installation « All Tutorial Fan
  8. 20 Steps to a Flexible and Secure WordPress Installation | LionWebMedia.com
  9. 20 Steps to a Flexible and Secure WordPress Installation | Customize Wordpress Templates
  10. Mengkompress Manual Javascript dan CSS dengan Deflate di .htaccess | Hikaru {Aka} Yuuki のブログ
  11. Manually Compress Javascript dan CSS with PHP GZip | Hikaru {Aka} Yuuki のブログ

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.