PHP 怎么PHP Last-Modified

wen PHP项目 1

本文目录导读:

PHP 怎么PHP Last-Modified

  1. 基础用法:设置 Last-Modified 头
  2. 完整示例:带缓存验证的动态页面
  3. 结合 ETag 使用(推荐)
  4. 静态文件的处理
  5. 注意事项
  6. 最佳实践

在 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);

完整请求流程

  1. 首次请求:服务器发送 Last-Modified 头和完整内容
  2. 客户端缓存:浏览器存储内容和修改时间
  3. 再次请求:浏览器发送 If-Modified-Since
  4. 服务器对比:如果时间相同,返回 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 缓存机制,减少不必要的服务器负载和网络传输。

抱歉,评论功能暂时关闭!