WarpConduit Computing

  • Quick Tips
  • Web Design & Development
  • Graphic Design
  • Home
  • WordPress Plugins
  • Password Generator
  • About
  • Contact

Enabling Gzip Compression of PHP, CSS, and JS Files Without mod_deflate

October 23, 2010 by Josh Hartman

Normally you can easily enable Gzip compression using mod_deflate by adding the following lines to your .htaccess file:

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript
</IfModule>

<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript </IfModule>

But for those of you on shared hosts that don’t allow the mod_deflate module and run PHP in CGI/FastCGI mode you can’t go with the easy method.

So, to serve up your PHP, CSS, and JS files you can try the following method.

Note 1: Your shared web hosting account must support custom php.ini and .htaccess files.

Note 2: Be careful when mixing this solution with other cache/compression applications.

Step 1: PHP Configuration

Add or modify the following lines in your custom php.ini file:

output_handler = Off
zlib.output_compression = On
zlib.output_handler = ob_gzhandler

output_handler = Off zlib.output_compression = On zlib.output_handler = ob_gzhandler

Now this will take care of gzipping all PHP files.

Step 2: .htaccess Configuration

Add the following lines to the bottom of a .htaccess file in the root of your website.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*\.js) gzip.php?type=js&file=$1
RewriteRule ^(.*\.css) gzip.php?type=css&file=$1
</IfModule>

<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*\.js) gzip.php?type=js&file=$1 RewriteRule ^(.*\.css) gzip.php?type=css&file=$1 </IfModule>

This will redirect all requests for .css and .js files through gzip.php, which we will create in the next step.

Step 3: File Processing PHP Script

The following PHP script will inherently use the PHP compression you’ve already enabled and also add headers to your files take advantage of your client’s browser cache to make subsequent loads faster.

Create a file named gzip.php in your website’s root and add the following lines to it:

<?php
//check that zlib compression is enabled
if(!ini_get('zlib.output_compression')){ die(); }
 
$allowed = array('css','js'); //set array of allowed file types to prevent abuse
 
//check for request variable existence and that file type is allowed
if(isset($_GET['file']) && isset($_GET['type']) && in_array(substr($_GET['file'],strrpos($_GET['file'],'.')+1), $allowed)){
	$data = file_get_contents(dirname(__FILE__).'/'.$_GET['file']); // grab the file contents
 
	$etag = '"'.md5($data).'"'; // generate a file Etag
	header('Etag: '.$etag); // output the Etag in the header
 
	// output the content-type header for each file type
	switch ($_GET['type']) {
		case 'css':
			header ("Content-Type: text/css; charset: UTF-8");
		break;
 
		case 'js':
			header ("Content-Type: text/javascript; charset: UTF-8");
		break;
	}
 
	header('Cache-Control: max-age=300, must-revalidate'); //output the cache-control header
	$offset = 60 * 60;
	$expires = 'Expires: ' . gmdate('D, d M Y H:i:s',time() + $offset) . ' GMT'; // set the expires header to be 1 hour in the future
	header($expires); // output the expires header
 
	// check the Etag the browser already has for the file and only serve the file if it is different
	if ($etag == $_SERVER['HTTP_IF_NONE_MATCH']) {
		header('HTTP/1.1 304 Not Modified');
		header('Content-Length: 0');
	} else {
		echo $data;
	}
}
?>

<?php //check that zlib compression is enabled if(!ini_get('zlib.output_compression')){ die(); } $allowed = array('css','js'); //set array of allowed file types to prevent abuse //check for request variable existence and that file type is allowed if(isset($_GET['file']) && isset($_GET['type']) && in_array(substr($_GET['file'],strrpos($_GET['file'],'.')+1), $allowed)){ $data = file_get_contents(dirname(__FILE__).'/'.$_GET['file']); // grab the file contents $etag = '"'.md5($data).'"'; // generate a file Etag header('Etag: '.$etag); // output the Etag in the header // output the content-type header for each file type switch ($_GET['type']) { case 'css': header ("Content-Type: text/css; charset: UTF-8"); break; case 'js': header ("Content-Type: text/javascript; charset: UTF-8"); break; } header('Cache-Control: max-age=300, must-revalidate'); //output the cache-control header $offset = 60 * 60; $expires = 'Expires: ' . gmdate('D, d M Y H:i:s',time() + $offset) . ' GMT'; // set the expires header to be 1 hour in the future header($expires); // output the expires header // check the Etag the browser already has for the file and only serve the file if it is different if ($etag == $_SERVER['HTTP_IF_NONE_MATCH']) { header('HTTP/1.1 304 Not Modified'); header('Content-Length: 0'); } else { echo $data; } } ?>

Great! With these steps in place your css and javascript files will be processed by gzip.php and output using PHP’s gzip compression library (zlib).

This method can be extended to more filetypes by adding to the allowed file types in gzip.php and adding more lines to your .htaccess file.

Filed Under: Web Design & Development Tagged With: css, deflate, gzip, htaccess, javascript, php

Comments

  1. Share bookmarks says

    August 17, 2011 at 10:53 PM

    Very great post. I just stumbled upon your weblog and wanted to say that I have really enjoyed surfing around your weblog posts. In any case I will be subscribing to your feed and I hope you write again very soon!

  2. blfeigel says

    May 5, 2012 at 10:34 AM

    I tried this out on a test site, but it made my browser level caching stop working and when I tried to remove it all my pages are redirecting to 404 pages. I can still get to the WordPress Dashboard and the homepage of the site, but that’s it. Other than deleting the code is there something special I have to do to turn this off?

    • Josh Hartman says

      May 5, 2012 at 3:28 PM

      No, but it sounds like your server is probably caching your .htaccess file. By the time you get this reply everything will probably be back to normal for you, but if not try emptying your .htaccess file and include only these WordPress rules:

      # BEGIN WordPress
      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteBase /
      RewriteRule ^index.php$ - [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.php [L]
      </IfModule>
       
      # END WordPress

      # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress

      If the site is in a subdirectory, like /wordpress/, it should look like this:

      # BEGIN WordPress
      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteBase /wordpress/
      RewriteRule ^index.php$ - [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /wordpress/index.php [L]
      </IfModule>
       
      # END WordPress

      # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /wordpress/ RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /wordpress/index.php [L] </IfModule> # END WordPress

      Also, don’t forget to clear your browser cache.
      For gzip under WordPress you may want to try a caching plugins and also take a look at this Tuts+ article.

Connect

  • Facebook
  • GitHub
  • RSS
  • Twitter
  • YouTube

Recent Posts

  • Extremely Useful Applications for Web Development and IT Tasks
  • Installing BookStack Wiki on cPanel Shared Hosting
  • Media (MIME) Type Reference List

Tags

automatic base64 benchmark cache counter css deflate email font gzip htaccess html image inarray increment inline images in_array javascript jquery link list magento mailto menu metadot mysql number obfuscation opencart operating system order php random redirect rewriterule slashes software timestamp ubuntu unix upgrade url windows windows 7 wordpress

Blogroll

  • CodeIgniter
  • Fusion Forward
  • jQuery
  • Nettuts+
  • Smashing Magazine

© 2021 WarpConduit Computing. All Rights Reserved.