Reputation: 68
Imagine that your server does not support deflate and gzip module on Apache. In this case there are several ways to compress your data.
I use the Apache rewrite module and php gzip extension to do this.
I created one file named gzip.php to get $_SERVER['REQUEST_URI'], get its content, set headers, compress and flush content as a file.
I kept the extension of all files so apache preserves the file types.
I added these lines to .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^((.*)\.(js|css))$ gzip.php [L]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
I've added these headers to my files:
$src = $_SERVER['REQUEST_URI'];
// seconds, minutes, hours, days
$expires = 60*60*24*14;
ob_start();
ob_implicit_flush(0);
header("Pragma: public");
header("Cache-Control: maxage=".$expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
// Then do everything you want to do on the page
$path = PUBLIC_DIR . $src;
$info = pathinfo($path);
$ext = strtolower($info['extension']);
include_once 'Entezar/File.php';
$mimeType = Entezar_File::getMimeType($path);
header("Content-type: $mimeType");
if (file_exists($path) && in_array($ext, array('js', 'css'))) {
$fs = stat($path);
header("Etag: ".sprintf('"%x-%x-%s"', $fs['ino'], $fs['size'],base_convert(str_pad($fs['mtime'],16,"0"),10,16)));
echo file_get_contents($path);
}
unset($path, $src, $info, $ext);
My problem is that when I use apache rewrite module along php with to compress contents, FireFox does not load my files (css or js) from the cache at all! Can anybody help me?!
Upvotes: 1
Views: 6538
Reputation: 68
Digger's Finder! Before doing any work(compress some files in gzip.php file) you should check these two keys in $_SERVER variable(Of course you should set expiration and cache headers in somewhere such as apache .htaccess file or other place... ):
$etag = '"' . md5($contents) . '"';
$etag_header = 'Etag: ' . $etag;
header($etag_header);
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) and $_SERVER['HTTP_IF_NONE_MATCH']==$etag) {
header("HTTP/1.1 304 Not Modified");
exit();
}
In apache .htaccess add these lines:
<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
ExpiresByType text/html "access plus 1 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
</ifModule>
<ifModule mod_headers.c>
<filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
<filesMatch "\\.(css)$">
Header set Cache-Control "max-age=604800, public"
</filesMatch>
<filesMatch "\\.(js)$">
Header set Cache-Control "max-age=216000, private"
</filesMatch>
<filesMatch "\\.(xml|txt)$">
Header set Cache-Control "max-age=216000, public, must-revalidate"
</filesMatch>
<filesMatch "\\.(html|htm|php)$">
Header set Cache-Control "max-age=1, private, must-revalidate"
</filesMatch>
</ifModule>
Upvotes: 4