【问题标题】:What is an efficient way to cache (auto version) a php file that is created by combining multiple css files?缓存(自动版本)通过组合多个css文件创建的php文件的有效方法是什么?
【发布时间】:2026-01-04 07:45:01
【问题描述】:

我有一个名为 main.css.php 的 php 文件,它收集多个 css 文件并将它们输出为一个大 css 文件。它收集的 css 文件数量范围为 1-10。代码是这样的:

header('Content-type: text/css');
header('Cache-Control: max-age=31536000');
ob_start("compress");
function compress($buffer) {
    /* remove comments */
    $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
    /* remove tabs, spaces, newlines, etc. */
    $buffer = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $buffer);
    return $buffer;
}

// include css files
foreach ($css_files as $path) {
    if (file_exists($path)) {
        include_once($path);
    }
}
ob_end_flush();

所以我已经对这部分进行了排序,但现在我不确定如何缓存它,如果任何原始 css 文件发生更改,我可以更新缓存。正如this answer 中所建议的那样,我打算这样做:

$cache = "";
foreach ($css_files as $path) {
    $cache.= filemtime($path);
}
...
echo "<link rel='stylesheet' href='/css/base.{$cache}.css'>";

但是我不能使用这个 apache 重写规则:

RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]

由于我不确定 $cache 将包含多个 unix 时间戳,因此我不确定它的长度。

总结

我需要将多个 css 文件合并为一个 php 文件,该文件使用 css 标头发送到浏览器。然后我需要正确缓存此文件,但如果任何原始 css 文件发生更改,我可以通过一种方式更新缓存。

对于我正在做的事情的任何建议、建议或更好的方法将不胜感激。

【问题讨论】:

    标签: php css http caching auto-versioning


    【解决方案1】:

    您应该对$cache 变量进行哈希处理并在文件名中使用它。应该是这样的:

    <?php
    
    $cache = "";
    foreach ($css_files as $path) {
        $cache .= filemtime($path);
    }
    
    $cache = md5($cache);
    

    而您的重写规则将使用哈希函数的长度;在这种情况下,我们使用md5,长度为 32 个字符:

    RewriteEngine on
    RewriteRule ^(.*)\.[\d]{32}\.(css|js)$ $1.$2 [L]
    

    希望有帮助

    【讨论】:

    • 我对散列不太熟悉,但看起来它会起作用,试一试。
    【解决方案2】:

    为什么不在磁盘上存储缓存信息?这样您就无需担心 .htaccess。

    $prevTimes = filegetcontents('/cache/css.txt')
    if(array_sum($filetimes) != (int) $prevTimes){
      //recompile css
      //update csscacheinfo.txt with $newTimes
      //echo css file link for stylesheet using $newTimes.css as css file
    } else {
      //echo css file link for stylesheet using $prevTimes.css as css file
    }
    

    仅供参考:存储/添加整数比连接和比较字符串更快。

    【讨论】:

    • 如果被缓存了,浏览器怎么知道何时寻找新版本?
    • 这当然是一个更清洁的解决方案,但您的 FYI 评论具有误导性;通过避免字符串连接而获得的任何微秒性能都会因转到磁盘并在每次访问页面时转换为 int 而丢失。但是,同样,差别很小,所以这仍然是缓存文件的最佳方式。
    • @wavemode PHP 不断地从磁盘读取文件。要求等。在我的评论中,我只是指他将所有时间加在一起作为字符串的事实。所以他在转换数据类型,然后构建一个新的字符串,然后大概比较字符串。
    • @joshhunt 只需更改文件名。例如,您可以使用文件修改时间的总和。如果浏览器读取一个新的文件 URL,它将加载更改,因为它没有缓存该文件。
    • 正确,这就是 .htaccess 重写的目的,因此它是自动化的。除非我错过了什么?