简介PHP的Yii框架中缓存的一些高级用法


Posted in PHP onMarch 29, 2016

页面缓存
页面缓存指的是在服务器端缓存整个页面的内容。随后当同一个页面被请求时,内容将从缓存中取出,而不是重新生成。

页面缓存由 yii\filters\PageCache 类提供支持,该类是一个过滤器。它可以像这样在控制器类中使用:

public function behaviors()
{
 return [
  [
   'class' => 'yii\filters\PageCache',
   'only' => ['index'],
   'duration' => 60,
   'variations' => [
    \Yii::$app->language,
   ],
   'dependency' => [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT COUNT(*) FROM post',
   ],
  ],
 ];
}

上述代码表示页面缓存只在 index 操作时启用,页面内容最多被缓存 60 秒,会随着当前应用的语言更改而变化。如果文章总数发生变化则缓存的页面会失效。

如你所见,页面缓存和片段缓存极其相似。它们都支持 duration,dependencies,variations 和 enabled 配置选项。它们的主要区别是页面缓存是由过滤器实现,而片段缓存则是一个小部件。

你可以在使用页面缓存的同时,使用片段缓存和动态内容。

HTTP 缓存

除了服务器端缓存外, Web 应用还可以利用客户端缓存去节省相同页面内容的生成和传输时间。

通过配置 yii\filters\HttpCache 过滤器,控制器操作渲染的内容就能缓存在客户端。yii\filters\HttpCache 过滤器仅对 GET 和 HEAD 请求生效,它能为这些请求设置三种与缓存有关的 HTTP 头。

  • yii\filters\HttpCache::lastModified
  • yii\filters\HttpCache::etagSeed
  • yii\filters\HttpCache::cacheControlHeader

Last-Modified 头

Last-Modified 头使用时间戳标明页面自上次客户端缓存后是否被修改过。

通过配置 yii\filters\HttpCache::lastModified 属性向客户端发送 Last-Modified 头。该属性的值应该为 PHP callable 类型,返回的是页面修改时的 Unix 时间戳。该 callable 的参数和返回值应该如下:

/**
 * @param Action $action 当前处理的操作对象
 * @param array $params “params” 属性的值
 * @return integer 页面修改时的 Unix 时间戳
 */
function ($action, $params)

以下是使用 Last-Modified 头的示例:

public function behaviors()
{
 return [
  [
   'class' => 'yii\filters\HttpCache',
   'only' => ['index'],
   'lastModified' => function ($action, $params) {
    $q = new \yii\db\Query();
    return $q->from('post')->max('updated_at');
   },
  ],
 ];
}

上述代码表明 HTTP 缓存只在 index 操作时启用。它会基于页面最后修改时间生成一个 Last-Modified HTTP 头。当浏览器第一次访问 index 页时,服务器将会生成页面并发送至客户端浏览器。之后客户端浏览器在页面没被修改期间访问该页,服务器将不会重新生成页面,浏览器会使用之前客户端缓存下来的内容。因此服务端渲染和内容传输都将省去。

ETag 头

“Entity Tag”(实体标签,简称 ETag)使用一个哈希值表示页面内容。如果页面被修改过,哈希值也会随之改变。通过对比客户端的哈希值和服务器端生成的哈希值,浏览器就能判断页面是否被修改过,进而决定是否应该重新传输内容。

通过配置 yii\filters\HttpCache::etagSeed 属性向客户端发送 ETag 头。该属性的值应该为 PHP callable 类型,返回的是一段种子字符用来生成 ETag 哈希值。该 callable 的参数和返回值应该如下:

/**
 * @param Action $action 当前处理的操作对象
 * @param array $params “params” 属性的值
 * @return string 一段种子字符用来生成 ETag 哈希值
 */
function ($action, $params)

以下是使用 ETag 头的示例:

public function behaviors()
{
 return [
  [
   'class' => 'yii\filters\HttpCache',
   'only' => ['view'],
   'etagSeed' => function ($action, $params) {
    $post = $this->findModel(\Yii::$app->request->get('id'));
    return serialize([$post->title, $post->content]);
   },
  ],
 ];
}

上述代码表明 HTTP 缓存只在 view 操作时启用。它会基于用户请求的标题和内容生成一个 ETag HTTP 头。当浏览器第一次访问 view 页时,服务器将会生成页面并发送至客户端浏览器。之后客户端浏览器标题和内容没被修改在期间访问该页,服务器将不会重新生成页面,浏览器会使用之前客户端缓存下来的内容。因此服务端渲染和内容传输都将省去。

ETag 相比 Last-Modified 能实现更复杂和更精确的缓存策略。例如,当站点切换到另一个主题时可以使 ETag 失效。

复杂的 Etag 生成种子可能会违背使用 HttpCache 的初衷而引起不必要的性能开销,因为响应每一次请求都需要重新计算 Etag。请试着找出一个最简单的表达式去触发 Etag 失效。

注意:为了遵循 RFC 7232(HTTP 1.1 协议),如果同时配置了 ETag 和 Last-Modified 头,HttpCache 将会同时发送它们。并且如果客户端同时发送 If-None-Match 头和 If-Modified-Since 头,则只有前者会被接受。
Cache-Control 头

Cache-Control 头指定了页面的常规缓存策略。可以通过配置 yii\filters\HttpCache::cacheControlHeader 属性发送相应的头信息。默认发送以下头:

Cache-Control: public, max-age=3600

会话缓存限制器

当页面使 session 时,PHP 将会按照 PHP.INI 中所设置的 session.cache_limiter 值自动发送一些缓存相关的 HTTP 头。这些 HTTP 头有可能会干扰你原本设置的 HttpCache 或让其失效。为了避免此问题,默认情况下 HttpCache 禁止自动发送这些头。想改变这一行为,可以配置 yii\filters\HttpCache::sessionCacheLimiter 属性。该属性接受一个字符串值,包括 public,private,private_no_expire,和 nocache。请参考 PHP 手册中的缓存限制器了解这些值的含义。

SEO 影响

搜索引擎趋向于遵循站点的缓存头。因为一些爬虫的抓取频率有限制,启用缓存头可以可以减少重复请求数量,增加爬虫抓取效率(译者:大意如此,但搜索引擎的排名规则不了解,好的缓存策略应该是可以为用户体验加分的)。

 

PHP 相关文章推荐
php中文本操作的类
Mar 17 PHP
Phpbean路由转发的php代码
Jan 10 PHP
php生成的html meta和link标记在body标签里 顶部有个空行
May 18 PHP
比较全面的PHP数组的使用方法小结
Sep 23 PHP
php 数组排序 array_multisort与uasort的区别
Mar 24 PHP
PHP处理excel cvs表格的方法实例介绍
May 13 PHP
php通过正则表达式记取数据来读取xml的方法
Mar 09 PHP
php实现从上传文件创建缩略图的方法
Apr 02 PHP
PHP在线书签系统分享
Jan 04 PHP
Zend Framework基本页面布局分析
Mar 19 PHP
Thinkphp5.0自动生成模块及目录的方法详解
Apr 17 PHP
laravel框架模型和数据库基础操作实例详解
Jan 25 PHP
深入解析PHP的Yii框架中的缓存功能
Mar 29 #PHP
PHP实现可自定义样式的分页类
Mar 29 #PHP
PHP的Yii框架中View视图的使用进阶
Mar 29 #PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
Mar 29 #PHP
PHP的Yii框架中Model模型的学习教程
Mar 29 #PHP
php ajax异步读取rss文档数据
Mar 29 #PHP
详解PHP的Yii框架中的Controller控制器
Mar 29 #PHP
You might like
sqlyog 中文乱码问题的设置方法
2008/10/19 PHP
php微信公众号开发之图片回复
2018/10/20 PHP
mouse_on_title.js
2006/08/25 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
创建、调用JavaScript对象的方法集锦
2014/12/24 Javascript
JavaScript jQuery 中定义数组与操作及jquery数组操作
2015/12/18 Javascript
js中实现字符串和数组的相互转化详解
2016/01/24 Javascript
jQuery的事件预绑定
2016/12/05 Javascript
js实现百度地图定位于地址逆解析,显示自己当前的地理位置
2016/12/08 Javascript
vue.js仿hover效果的实现方法示例
2019/01/28 Javascript
微信小程序实现卡片层叠滑动效果
2019/06/21 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
2020/02/15 Javascript
Postman动态获取返回值过程详解
2020/06/30 Javascript
Python简单生成8位随机密码的方法
2017/05/24 Python
从CentOS安装完成到生成词云python的实例
2017/12/01 Python
使用python对excle和json互相转换的示例
2018/10/23 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
2019/06/13 Python
python中tkinter的应用:修改字体的实例讲解
2019/07/17 Python
Python 字符串、列表、元组的截取与切片操作示例
2019/09/17 Python
基于virtualenv创建python虚拟环境过程图解
2020/03/30 Python
tensorflow 20:搭网络,导出模型,运行模型的实例
2020/05/26 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
html5 Canvas画图教程(5)—canvas里画曲线之arc方法
2013/01/09 HTML / CSS
方太官方网上商城:销售方太抽油烟机、燃气灶、消毒柜等
2017/01/17 全球购物
草莓网化妆品澳大利亚站:Strawberrynet AU
2017/12/18 全球购物
以设计师精品品质提供快速时尚:Mostata
2019/05/10 全球购物
新东方旗下远程教育网站:新东方在线
2020/03/19 全球购物
全球最大运动品牌的男装、女装和童装官方库存商:A&A Sports
2021/01/17 全球购物
TUMI香港官网:国际领先的行李箱、背囊品牌
2021/03/01 全球购物
社会实践评语
2014/04/28 职场文书
2015年团支书工作总结
2015/04/03 职场文书
工会经费申请报告
2015/05/15 职场文书
2015中学教师个人工作总结
2015/07/22 职场文书
立秋之描写立秋的作文(五年级)
2019/08/08 职场文书
基于Redission的分布式锁实战
2022/08/14 Redis