为何If-modified-since对HTML文件生效却对PHP文件无效?
Why PHP Doesn't Support If-Modified-Since (And How to Fix It)
嘿,这个问题我之前帮不少开发者捋清楚过——其实核心原因是静态HTML和动态PHP的缓存处理逻辑完全不一样:
为什么HTML支持,PHP不支持?
静态HTML文件是服务器(比如Apache、Nginx)直接托管的资源,服务器会自动帮你处理缓存相关的HTTP头:
- 当第一次请求HTML文件时,服务器会读取文件的最后修改时间,返回
Last-Modified响应头给客户端; - 当客户端再次请求时,会带上
If-Modified-Since头(值就是之前拿到的Last-Modified时间); - 服务器对比这个时间和文件当前的修改时间,如果没变化,直接返回
304 Not Modified,节省带宽。
但PHP是动态脚本,服务器默认只会执行PHP代码并输出内容,不会自动帮你添加Last-Modified或者处理If-Modified-Since请求头——所以检测工具会判定PHP文件不支持这个功能。
具体修复方法
要让PHP支持If-Modified-Since,你需要手动在代码里添加缓存头的处理逻辑,步骤很清晰:
1. 获取内容的最后修改时间
如果你的PHP页面是复刻自某个静态HTML文件,直接用filemtime()获取该文件的修改时间即可;如果是动态生成的内容(比如从数据库拉取的内容),需要自己维护一个内容更新时间(比如存在数据库字段、配置文件里)。
2. 对比客户端的If-Modified-Since时间
解析请求头里的If-Modified-Since值,转换成时间戳后和内容的最后修改时间对比:
- 如果客户端的时间不早于内容修改时间,说明内容没更新,直接返回
304 Not Modified状态码,终止脚本; - 如果内容有更新,输出正常内容,同时设置
Last-Modified响应头。
完整代码示例
<?php // 假设你的复刻内容基于original.html文件 $sourceFile = 'original.html'; $contentLastModified = filemtime($sourceFile); // 读取客户端请求头中的If-Modified-Since $clientIfModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? false; $clientTimestamp = $clientIfModifiedSince ? strtotime($clientIfModifiedSince) : 0; // 对比时间:如果客户端缓存的内容是最新的,返回304 if ($clientTimestamp >= $contentLastModified) { header('HTTP/1.1 304 Not Modified'); exit; // 终止脚本,不输出内容 } // 设置缓存响应头 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $contentLastModified) . ' GMT'); // 可选:添加Cache-Control头增强缓存效果 header('Cache-Control: public, max-age=3600'); // 输出页面内容(这里直接读取并输出源HTML文件) readfile($sourceFile); ?>
额外注意事项
- 确保服务器的系统时间是准确的,否则时间对比会出现错误;
- 如果是动态内容(比如数据库驱动的页面),把
$contentLastModified替换成你维护的内容更新时间戳即可; - 可以根据需求调整
Cache-Control的参数,比如max-age设置缓存有效期(单位:秒)。
内容的提问来源于stack exchange,提问作者MLS
相关产品推荐
相关产品推荐

