作为对下面发布的 compress() 函数的扩展,这里有一个简洁的小类,它稍微改进了这个想法。基本上,为每个页面加载运行所有 CSS 的 compress() 函数显然远远不是最佳选择,尤其是考虑到样式最多只会偶尔更改。
使用这个类,你可以简单地指定一个 CSS 文件名数组并调用 dump_style()。每个文件的内容都以 compress() 形式保存在缓存文件中,只有当相应的源 CSS 更改时才会重新创建缓存文件。
它适用于 PHP5,但如果你只是取消 OOP 所有东西,并可能定义 file_put_contents,它将以相同的方式工作。
享受!
<?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;
}
}
?>