CSS 檔案更新後,瀏覽器若快取舊版本會導致頁面樣式錯亂。常見解法是在引用 URL 後附加版本參數:style.css?v=20240101。CSSUpdate 類別自動掃描 CSS 範本中的圖片/資源引用,批次更新版本號並輸出至正式目錄。
<?php
class CSSUpdate {
private $csstmpl_path, $css_path, $replacetags, $search_child;
private $convert_num = 0, $is_ready = 0;
public function __construct($csstmpl_path, $css_path, array $replacetags, $search_child = false) {
if (!is_dir($csstmpl_path) || !is_dir($css_path) || !$replacetags) {
$this->is_ready = 0;
} else {
$this->csstmpl_path = $csstmpl_path;
$this->css_path = $css_path;
$this->replacetags = $replacetags; // 如 ['png','jpg','gif','css','js']
$this->search_child = $search_child;
$this->is_ready = 1;
}
}
public function update() {
if (!$this->is_ready) return;
$this->traversing($this->csstmpl_path);
echo "Convert count: {$this->convert_num}";
}
private function traversing($path) {
$files = scandir($path);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$full = $path . '/' . $file;
if (is_dir($full)) {
if ($this->search_child) $this->traversing($full);
} elseif (pathinfo($file, PATHINFO_EXTENSION) === 'css') {
$this->processFile($full);
}
}
}
private function processFile($srcFile) {
$content = file_get_contents($srcFile);
$newContent = $this->replaceVersions($content);
$destFile = str_replace($this->csstmpl_path, $this->css_path, $srcFile);
$this->createDirs(dirname($destFile));
file_put_contents($destFile, $newContent);
$this->convert_num++;
}
private function replaceVersions($css) {
$pattern = '/(url\([\'"]?)([^\'")]+)(\.(' . implode('|', $this->replacetags) . '))([\'"]?\))/i';
return preg_replace_callback($pattern, function($m) {
$version = date('YmdHis'); // 或 git commit hash、檔案 mtime
return $m[1] . $m[2] . $m[3] . '?v=' . $version . $m[5];
}, $css);
}
private function createDirs($dir) {
if (!is_dir($dir)) mkdir($dir, 0755, true);
}
}
<?php
require 'CSSUpdate.class.php';
$updater = new CSSUpdate(
'/var/www/project/css_tmpl', // 範本目錄
'/var/www/project/public/css', // 輸出目錄
['png', 'jpg', 'jpeg', 'gif', 'css', 'js', 'woff', 'woff2'], // 需加版本的資源類型
true // 遞歸子目錄
);
$updater->update();
php update_css.php。md5_file() / filemtime():內容不變則版本不變,快取命中率最高。Cache-Control: max-age=31536000, immutable,配合版本參數實現長效快取與精準失效。contenthash 自動生成帶雜湊的檔案名 (style.a1b2c3.css),無需查詢字串版本。manifest.json 對應原始檔名與雜湊檔名,模板引擎讀取渲染。CSSUpdate 以純 PHP 解決傳統專案 CSS/靜態資源快取失效問題,零依賴、易整合現有部署流程。現代前端工程化專案建議遷移至建置工具原生的雜湊檔名機制,徹底消除快取煩惱。