本文目录导读:

在 PHP 中处理 Last-Modified 头主要用于HTTP 缓存,让浏览器和服务器之间进行条件请求验证,从而减少数据传输。
以下是完整的使用方法和示例:
基础用法:设置 Last-Modified 头
<?php
// 设置最后修改时间(必须使用 GMT 格式)
$lastModified = gmdate('D, d M Y H:i:s', time()) . ' GMT';
header('Last-Modified: ' . $lastModified);
?>
完整示例:带缓存验证的动态页面
<?php
// 假设你的内容最后修改时间(例如数据库中记录的)
$lastModifiedTime = strtotime('2024-01-15 10:30:00');
// 转换为 HTTP 格式
$lastModified = gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT';
// 设置 Last-Modified 头
header('Last-Modified: ' . $lastModified);
// 检查客户端是否发送了 If-Modified-Since 头
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
// 解析客户端的时间
$clientModified = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
// 如果客户端缓存是最新的
if ($clientModified >= $lastModifiedTime) {
// 返回 304 Not Modified 状态码
header('HTTP/1.1 304 Not Modified');
exit; // 不再输出内容
}
}
已更新,才输出完整内容
echo "这是页面内容...";
?>
结合 ETag 使用(推荐)
<?php
$content = "这是动态生成的内容";
$lastModifiedTime = filemtime(__FILE__); // 或其他时间源
// 生成 ETag(基于内容哈希)
$etag = md5($content . $lastModifiedTime);
// 设置缓存相关头
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT');
header('ETag: "' . $etag . '"');
header('Cache-Control: public, max-age=3600');
// 检查 If-None-Match 和 If-Modified-Since
$httpIfNoneMatch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : '';
$httpIfModifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : 0;
// 判断是否需要发送 304
$notModified = false;
// ETag 优先考虑
if ($httpIfNoneMatch && $httpIfNoneMatch == '"' . $etag . '"') {
$notModified = true;
}
// 然后检查 Last-Modified
elseif ($httpIfModifiedSince && $httpIfModifiedSince >= $lastModifiedTime) {
$notModified = true;
}
if ($notModified) {
header('HTTP/1.1 304 Not Modified');
exit;
}
// 输出完整内容
echo $content;
?>
静态文件的处理
如果是静态文件,可以直接设置,但更推荐使用服务器配置(如 Nginx/Apache):
<?php
$file = '/path/to/your/file.pdf';
if (file_exists($file)) {
$lastModifiedTime = filemtime($file);
header('Content-Type: application/pdf');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT');
// 检查条件请求
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$ifModifiedSince = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ($ifModifiedSince >= $lastModifiedTime) {
header('HTTP/1.1 304 Not Modified');
exit;
}
}
// 输出文件
readfile($file);
}
?>
注意事项
时间格式必须正确
// 正确的格式
$gmtDate = gmdate('D, d M Y H:i:s', time()) . ' GMT';
// 示例输出: Mon, 15 Jan 2024 10:30:00 GMT
使用缓存控制策略
// 示例:组合使用
header('Cache-Control: private, must-revalidate');
header('Last-Modified: ' . $lastModified);
完整请求流程
- 首次请求:服务器发送
Last-Modified头和完整内容 - 客户端缓存:浏览器存储内容和修改时间
- 再次请求:浏览器发送
If-Modified-Since头 - 服务器对比:如果时间相同,返回 304 状态码,不发送内容
完整示例:动态内容缓存
<?php
// 模拟数据库查询
function getContentModifiedTime() {
// 实际应用中返回内容的最后修改时间
return strtotime('2024-01-20 14:00:00');
}
// 主逻辑
$lastModifiedTime = getContentModifiedTime();
$lastModified = gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT';
header('Last-Modified: ' . $lastModified);
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$ifModifiedSince = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ($ifModifiedSince >= $lastModifiedTime) {
header('HTTP/1.1 304 Not Modified');
exit;
}
}
有更新时才重新生成
$content = "最新内容 - 更新时间: " . date('Y-m-d H:i:s', $lastModifiedTime);
echo $content;
?>
最佳实践
- 优先使用 ETag:ETag 比 Last-Modified 更精确
- 组合使用:两者可以同时使用
- 配合 Cache-Control:设置合适的缓存策略
- 注意时区:始终使用 GMT 格式
- 验证条件:
If-Modified-Since优先于If-Modified-Since的处理顺序
这样实现后,你的 PHP 页面就能正确利用 HTTP 缓存机制,减少不必要的服务器负载和网络传输。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播