首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP CSS 版本自動更新類 CSSUpdate:解決瀏覽器快取導致樣式不生效

     編輯:PHP 綜合知識

問題背景

CSS 檔案更新後,瀏覽器若快取舊版本會導致頁面樣式錯亂。常見解法是在引用 URL 後附加版本參數:style.css?v=20240101。CSSUpdate 類別自動掃描 CSS 範本中的圖片/資源引用,批次更新版本號並輸出至正式目錄。

核心類別結構 (CSSUpdate.class.php)

<?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();

部署整合建議

  • 構建腳本整合:在 CI/CD 流程 (Jenkins/GitLab CI/GitHub Actions) 的建置階段執行 php update_css.php。
  • 版本號策略:
    • 時間戳:簡單但每次建置皆不同,即使內容未變。
    • 檔案 md5_file() / filemtime():內容不變則版本不變,快取命中率最高。
    • Git Commit Hash:可追溯來源版本。
  • Nginx/Apache 快取配置:靜態資源設定 Cache-Control: max-age=31536000, immutable,配合版本參數實現長效快取與精準失效。

現代替代方案

  • Webpack/Vite/Rollup:前端建置工具內建 contenthash 自動生成帶雜湊的檔案名 (style.a1b2c3.css),無需查詢字串版本。
  • Manifest 檔案:建置產出 manifest.json 對應原始檔名與雜湊檔名,模板引擎讀取渲染。

結語

CSSUpdate 以純 PHP 解決傳統專案 CSS/靜態資源快取失效問題,零依賴、易整合現有部署流程。現代前端工程化專案建議遷移至建置工具原生的雜湊檔名機制,徹底消除快取煩惱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved