IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

PHP处理Etag、lastModified和Expires

超群.com的博客 2009-10-20 22:19:22 累计浏览 6,100 次
本机暂存

    之前看到robbin基于资源的HTTP Cache的实现介绍,想到这是一个很有意思的功能,原理很简单,但很多人都会忽略,于是乎打算集成到ColaPHP框架中来,让浏览器缓存动态内容,对于一些由动态脚本生成、更新不频繁但又会被用户重复访问的页面内容,还是很有意义的。

    如果在服务器端设置了Etag、lastModified和Expires之后,下次再访问同一资源的时候,一个典型的HTTP头是这样的:

以下是代码片段:
Host            127.0.0.1
User-Agent        Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 QQDownload/1.7
Accept            text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language        zh-cn,zh;q=0.5
Accept-Encoding        gzip,deflate
Accept-Charset        GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive        300
Connection        keep-alive
If-Modified-Since    Sat, 05 Sep 2009 12:44:56 GMT
If-None-Match        foobar
Cache-Control        max-age=0

    关于lastModified、Etag和Expires的工作原理,可以参看http://longrujun.name/index.php/2009/03/04/etag%E5%92%8Cexpires/,简单来说:

    lastModified:设定一个最后修改时间,浏览器下次访问的时候,发送一个”If-Modified-Sinc”的头信息,如果内容在这个时间之后没有更新,服务器直接返回一个304 Not Modified而不传输详细内容,可以节省带宽。

    Etag:设定一个标记,浏览器下次访问时,发送一个”If-None-Match”的头信息,如果服务器内容还是这个标记没变,也直接返回一个304 Not Modified而不传输详细内容,同样可以节省带宽。

    Expires:设定一个过期时间,如果当前请求在这个过期时间之类,则不发送HTTP请求,不仅可以节约服务器带宽,还可以减少服务器HTTP请求数

    主要通过header函数来发送,比较简单,直接上代码:

以下是代码片段:
public static function etag($etag, $notModifiedExit = true)
{
    if ($notModifiedExit && isset($_SERVER['HTTP_IF_NONE_MATCH']) && $etag == $_SERVER['HTTP_IF_NONE_MATCH']) {
        self::statusCode('304');
        exit();
    }
    header('Etag: ' . $etag);
}
 
public static function lastModified($modifiedTime, $notModifiedExit = true)
{
    $modifiedTime = date('D, d M Y H:i:s', $modifiedTime) . ' GMT';
    if ($notModifiedExit && isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $modifiedTime == $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
        self::statusCode('304');
        exit();
    }
    header("Last-Modified: $modifiedTime");
}
 
public static function expires($seconds = 1800)
{
    $time = date('D, d M Y H:i:s', time() + $seconds) . ' GMT';
    header("Expires: $time");
}

    如果你是用ColaPHP,可以直接在controller里面写上:

以下是代码片段:
// 设定最后修改时间,通常是数据库中内容修改时间
$this->helper->response->lastModified(1252154696);
// 设定内容标记,自己可以按照一定的规则来生成,当然也可以用内容最后修改的时间戳
 $this->helper->response->etag('foobar');
// 设定失效时间
$this->response->expires(10);

    PS:ColaPHP近期发0.3alpha,主要改进Model和DB设计,加入了一下小功能(比如验证码),以及bugfix。

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,270)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,408)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,150)
  5. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,790)
  6. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  7. Redis消息队列的若干实现方式 (累计阅读 12,088)
  8. 到底什么是MVC? (累计阅读 11,869)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,709)
  10. Rolling cURL: PHP并发最佳实践 (累计阅读 11,488)