以下是基於先前發布的 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;
}
}
?>