简介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速度全攻略
Oct 09 PHP
PHP中一个控制字符串输出的函数
Oct 09 PHP
用ADODB来让PHP操作ACCESS数据库的方法
Dec 31 PHP
php daodb插入、更新与删除数据
Mar 19 PHP
zend Framework中的Layout(模块化得布局)详解
Jun 28 PHP
ThinkPHP实现将本地文件打包成zip下载
Jun 26 PHP
PHP学习笔记(三):数据类型转换与常量介绍
Apr 17 PHP
thinkPHP中验证码的简单使用方法
Dec 26 PHP
PHP实现JS中escape与unescape的方法
Jul 11 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 PHP
使用WAMP搭建PHP本地开发环境
May 10 PHP
PHP基础之输出缓冲区基本概念、原理分析
Jun 19 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
php 文件夹删除、php清除缓存程序
2009/08/25 PHP
jquery的index方法实现tab效果
2011/02/16 Javascript
如何在一个页面显示多个百度地图
2013/04/07 Javascript
在JS数组特定索引处指定位置插入元素
2014/07/27 Javascript
DOM节点删除函数removeChild()用法实例
2015/01/12 Javascript
JavaScript分秒倒计时器实现方法
2015/02/02 Javascript
JavaScript中诡异的delete操作符
2015/03/12 Javascript
基于insertBefore制作简单的循环插空效果
2015/09/21 Javascript
Angular-Touch库用法示例
2016/12/22 Javascript
AngularJS执行流程详解
2017/02/17 Javascript
Vue中使用ElementUI使用第三方图标库iconfont的示例
2018/10/11 Javascript
vue实现路由监听和参数监听
2019/10/29 Javascript
vue.js iview打包上线后字体图标不显示解决办法
2020/01/20 Javascript
video.js添加自定义组件的方法
2020/12/09 Javascript
[03:09]2014DOTA2国际邀请赛 Mushi前队友送上祝福
2014/07/12 DOTA
Python实现扫描指定目录下的子目录及文件的方法
2014/07/16 Python
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
Python 实现数据库(SQL)更新脚本的生成方法
2017/07/09 Python
Python调用系统底层API播放wav文件的方法
2017/08/11 Python
pygame游戏之旅 如何制作游戏障碍
2018/11/20 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
python银行系统实现源码
2019/10/25 Python
python 无损批量压缩图片(支持保留图片信息)的示例
2020/09/22 Python
Python爬虫定时计划任务的几种常见方法(推荐)
2021/01/15 Python
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
Hotels.com印度:酒店预订
2019/05/11 全球购物
人力资源经理的岗位职责范本
2014/02/28 职场文书
平安建设工作方案
2014/06/02 职场文书
校庆口号
2014/06/20 职场文书
教师党员个人整改措施材料
2014/09/16 职场文书
2015年挂职干部工作总结
2015/05/14 职场文书
导游词之上饶龟峰
2019/10/25 职场文书
零基础学java之带返回值的方法的定义和调用
2022/04/10 Java/Android
python模拟浏览器 使用selenium进入好友QQ空间并留言
2022/04/12 Python
hive数据仓库新增字段方法
2022/06/25 数据库
python数据分析之单因素分析线性拟合及地理编码
2022/06/25 Python