In extension to the compress() function posted below, here's a nifty little class that improves the idea a bit. Basically, running that compress() function for all your CSS for every single page load is clearly far less than optimal, especially since the styles will change only infrequently at the very worst.
With this class you can simply specify an array of your CSS file names and call dump_style(). The contents of each file are saved in compress()'d form in a cache file that is only recreated when the corresponding source CSS changes.
It's intended for PHP5, but will work identically if you just un-OOP everything and possibly define file_put_contents.
Enjoy!
<?php
$CSS_FILES = array(
'_general.css'
);
$css_cache = new CSSCache($CSS_FILES);
$css_cache->dump_style();
class CSSCache {
private $filenames = array();
private $cwd;
public function __construct($i_filename_arr) {
if (!is_array($i_filename_arr))
$i_filename_arr = array($i_filename_arr);
$this->filenames = $i_filename_arr;
$this->cwd = getcwd() . DIRECTORY_SEPARATOR;
if ($this->style_changed())
$expire = -72000;
else
$expire = 3200;
header('Content-Type: text/css; charset: UTF-8');
header('Cache-Control: must-revalidate');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expire) . ' GMT');
}
public function dump_style() {
ob_start('ob_gzhandler');
foreach ($this->filenames as $filename)
$this->dump_cache_contents($filename);
ob_end_flush();
}
private function get_cache_name($filename, $wildcard = FALSE) {
$stat = stat($filename);
return $this->cwd . '.' . $filename . '.' .
($wildcard ? '*' : ($stat['size'] . '-' . $stat['mtime'])) . '.cache';
}
private function style_changed() {
foreach ($this->filenames as $filename)
if (!is_file($this->get_cache_name($filename)))
return TRUE;
return FALSE;
}
private function compress($buffer) {
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' '), '', $buffer);
$buffer = str_replace('{ ', '{', $buffer);
$buffer = str_replace(' }', '}', $buffer);
$buffer = str_replace('; ', ';', $buffer);
$buffer = str_replace(', ', ',', $buffer);
$buffer = str_replace(' {', '{', $buffer);
$buffer = str_replace('} ', '}', $buffer);
$buffer = str_replace(': ', ':', $buffer);
$buffer = str_replace(' ,', ',', $buffer);
$buffer = str_replace(' ;', ';', $buffer);
return $buffer;
}
private function dump_cache_contents($filename) {
$current_cache = $this->get_cache_name($filename);
if (is_file($current_cache)) {
include($current_cache);
return;
}
if ($dead_files = glob($this->get_cache_name($filename, TRUE), GLOB_NOESCAPE))
foreach ($dead_files as $dead_file)
unlink($dead_file);
$compressed = $this->compress(file_get_contents($filename));
file_put_contents($current_cache, $compressed);
echo $compressed;
}
}
?>