缓存php解析的css、js、txt文件

Posted

技术标签:

【中文标题】缓存php解析的css、js、txt文件【英文标题】:Caching css, js, txt files parsed by php 【发布时间】:2011-05-12 08:13:50 【问题描述】:

问题

我正在做一些实验,需要一些帮助。 我创建了 2 个文件。 ma​​in-real.css 是一个标准的普通 ol' css 文件,而 ma​​in.css 是由 php 解析并有一个 include() 抓取以前的真正 css文件。 以下是 ma​​in.css 的代码:

<?php 
include("main-real.css");
?>

然后我在我的 .htaccess 文件中添加一条指令,以使用 PHP 解析这个 css 文件:

<FilesMatch "main.css">
AddHandler application/x-httpd-php5 .css
Header Set Content-Type "text/css"
</FilesMatch> 

这在我运行 Apache 的 PHP 5.2 服务器上完美运行。 问题是该文件似乎没有被浏览器缓存,或者至少没有像常规的未经 PHP 解析的 CSS 文件那样返回 304 Not Modified 状态代码。

如果直接访问,以下是 ma​​in-real.css 的标头:

响应头 日期.......周四,2010 年 11 月 18 日 22:10:57 GMT 服务器............Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8i DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 最后修改.....周四,2010 年 11 月 18 日 22:10:23 GMT Etag.......“11b010a-26-4955b0e6671c0” 接受范围.....字节 内容长度....38 内容类型......文本/css 请求标头 接受......文本/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 接受语言....en-us,en;q=0.5 接受编码....gzip,deflate 接受字符集.....ISO-8859-1,utf-8;q=0.7,*;q=0.7 保活…………115 连接............保持活动状态 饼干......fc=fcVal=7625790752294348480 If-Modified-Since..Thu, 2010 年 11 月 18 日 22:10:23 GMT 如果-无匹配......“11b010a-26-4955b0e6671c0” 缓存控制......max-age=0

这里是 PHP 解析的 ma​​in.css 的标头:

响应头 日期......周四,2010 年 11 月 18 日 22:11:11 GMT 服务器............Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8i DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 X-Powered-By.......PHP/5.2.11 内容类型.......文本/css Keep-Alive.........超时=5,最大值=97 连接............保持活动 传输编码..chunked 请求标头 接受......文本/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 接受语言....en-us,en;q=0.5 接受编码....gzip,deflate 接受字符集.....ISO-8859-1,utf-8;q=0.7,*;q=0.7 保活…………115 连接............保持活动状态 饼干......fc=fcVal=7625790752294348480 缓存控制......max-age=0

我尝试过以各种方式修改 http-headers,添加 max-age、last-modified 和其他都没有成功。我有什么遗漏或误解吗?


解决方案和最终代码

主要缺少的代码是我需要在 include() 之前发送 Last-Modified 标头。这需要在 PHP 文件本身中完成!我之前尝试过使用 .htaccess Header set 指令添加 Last-Modified,虽然这确实添加了适当的标头,但它并没有触发缓存。 这是我的 ma​​in.css 的最终代码,带有遥远的未来 Expires 标头和 Cache-Control 以进行良好的衡量。

<?php
$last_modified = date("D, d M Y H:i:s \G\M\T", filemtime("main-shared.css"));
$expiration = date("D, d M Y H:i:s \G\M\T", strtotime('+1 year'));

header("Cache-Control: public, no-transform");
header("Expires: $expiration");
header("Last-Modified: $last_modified");

include("main-shared.css");
?>

【问题讨论】:

【参考方案1】:

Apache 为main-real.css 发送的标头是无关紧要的,因为您正在通过文件系统include() 对该文件进行输入。

在包含其他文件之前,您需要通过 PHP 脚本发送相同的标头。

header("Cache-Control: ........ ");
header("Expires: ....... ");
....
include("main-real.css"); 

【讨论】:

感谢您的回复。我添加了header("Cache-Control: public, no-transform"); header("Expires: Fri, 21 Dec 2015 01:01:01 GMT"); ,但仍然返回 200 OK 状态码。我在常规 CSS 文件和由 PHP 解析的文件之间看到的另一个区别是没有发送 If-Modified-SinceIf-None-Match 请求标头。为什么会这样?缓存是否有必要? @filip 也发送Last-modified。 if-**** 标头应该在某处:执行phpinfo() 并搜索它们 哇,只要我添加了Last-Modified 标头,使用filemtime() 生成的@mattbasta 就向我展示了,它完美地工作! If-Modified-Since 现在也出现在请求标头中。我之前尝试通过.htaccess 添加Last-Modified,这显然在这种情况下不起作用。非常感谢您的帮助。【参考方案2】:

您需要查看入站 HTTP 标头并确定 CSS 文件在此期间是否已合法更改。这意味着您将在请求标头中查看If-Modified-Since。下面是一些可以为你做的代码:

$last_modified = filemtime("main-real.css");
if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) 
    $expected_modified = strtotime(preg_replace('/;.*$/','',$_SERVER["HTTP_IF_MODIFIED_SINCE"]));
    if($last_modified <= $expected_modified) 
        header("HTTP/1.0 304 Not Modified");
        return;
    

【讨论】:

这很有意义,除了 If-Modified-Since 请求标头似乎没有发送! (我将我在 Firefox 中看到的请求标头添加到我的帖子中) 感谢您的回答,但是缺少的部分是我需要在包含之前发送Last-Modified,然后If-Modified-Since 标题正确显示,我得到一个自然的 304 Not Modified。我确实从您的代码中使用了 filemtime(),但我完全忘记了。谢谢。

以上是关于缓存php解析的css、js、txt文件的主要内容,如果未能解决你的问题,请参考以下文章

除了扩展名之外,.json、.txt、.html、.css 和 .js 文件之间有啥区别吗?

JS获取本地文件并且解析文件内容(XML,TXT)

ini 阻止搜索引擎在Nginx中索引.txt,.log,.xml,.css和.js文件

无法从 PHP 打开文件 [关闭]

PHP 使用 fopen 通过 URL 下载 txt 文件。如何限制下载量?

PHP 检查文件名