上图片根据Yii类参考手册,Yii源代码,开发常用方法构成。
图例说明
类图中主要包含了数据缓存的继承关系, 所有的数据缓存实现类, 都继承自yii\caching\Cache类. 除此之外, yii2还提供了页面缓存, 页面片段缓存 和 http(浏览器)缓存 的缓存实现.
概述
Yii2中, 支持数据缓存, 页面缓存, 页面片段缓存, Http浏览器缓存, 查询缓存(由数据缓存实现) 完善的缓存支持.
其中:
-
数据缓存, 提供通用的操作, 并支持主流的缓存服务器. 每种不同的服务器,有不同的功能驱动类完成实现.
-
查询缓存, 由上面的数据缓存负责实现.
-
页面缓存, 由Yii2中的过滤器(可以参考过滤器说明了解)实现.
-
HTTP浏览器缓存, 由Yii2中的过滤器(可以参考过滤器说明了解)实现.
-
页面片段缓存, 由部件(可以参考部件说明了解)实现.
数据缓存
将从数据源(通常是数据库)获取的数据, 存储在高速的缓存服务器中, 再次获取相同数据时, 就可以直接从缓存中获取, 而不必要再去数据源(通常是数据库)中获取了 .
常见的缓存服务器有: Memcahced, Redis, XCache, APC等. Yii2都提供了支持.
使用数据缓存, 需要2个步骤
1, 配置缓存组件. 2, 操作缓存数据(设置, 获取, 删除等)
1, 配置数据缓存组件
以通用的Memcached为例:
'components' => [ 'cache' => [ 'class' => 'yii\caching\MemCache', 'servers' => [ [ 'host' => 'server1', 'port' => 11211, 'weight' => 100, ], [ 'host' => 'server2', 'port' => 11211, 'weight' => 50, ], ], ],// 其他组件
以上配置中, 使用yii\caching\MemCache组件, 该组件基于PHP的memcached或memcache扩展 完成memcached服务器的管理. 这样, 在应用程序中, 就可以使用memcached服务器作为数据缓存服务器了.
PS: 其他缓存服务器的配置, 需要参考对应的组件才可以知道
2, 操作缓存数据(设置, 获取, 删除等)
配置好缓存组件后, 就可以通过该组件操作缓存了. Yii2对缓存做了抽象通用的操作, 提供了如下的操作:
-
yii\caching\Cache::get():通过一个指定的键(key)从缓存中取回一项数据。如果该项数据不存在于缓存中或者已经过期/失效,则返回值 false。
-
yii\caching\Cache::set():将一项数据指定一个键,存放到缓存中。
-
yii\caching\Cache::add():如果缓存中未找到该键,则将指定数据存放到缓存中。
-
yii\caching\Cache::mget():通过指定的多个键从缓存中取回多项数据。
-
yii\caching\Cache::mset():将多项数据存储到缓存中,每项数据对应一个键。
-
yii\caching\Cache::madd():将多项数据存储到缓存中,每项数据对应一个键。如果某个键已经存在于缓存中,则该项数据会被跳过。
-
yii\caching\Cache::exists():返回一个值,指明某个键是否存在于缓存中。
-
yii\caching\Cache::delete():通过一个键,删除缓存中对应的值。
-
yii\caching\Cache::flush():删除缓存中的所有数据。
加粗的就是最常用的设置, 获取, 删除 操作了
有了以上的方法, 在业务逻辑处理中(模型或控制器中), 就可以使用以下的代码完成通用的基于缓存的数据获取操作了:
// 尝试从缓存中取回 $data
$data = $cache->get($key);
if ($data === false) {
// $data 在缓存中没有找到,则重新计算它的值
// 将 $data 存放到缓存供下次使用
$cache->set($key, $data);
}
// 这儿 $data 可以使用了。
别忘了, 在数据源改变时, 将对应的缓存清除掉, 保证数据及时性:
$cache->get($key);
以上代码无论使用任何缓存服务器, 都是通用的. 仅仅需要更改缓存cache组件配置即可.
以上设置的缓存, 是不会主动失效的, 默认的有效期0, 为永久有效. 如果需要设置缓存时, 指定有效期, 请使用set()方法的第三个参数:
$cache->set($key, $data,3600);
查询缓存
查询缓存, 用于缓存SQL的查询结果, 类似于MySQL的Query-Cache, 只不过查询缓存是Yii2内部实现的, 而Query-Cache是MySQL实现的.
在Yii2中, 查询缓存是基于数据缓存实现的, 因此只要配置好了数据缓存组件 和 与数据缓存组件关联的数据库连接组件, 就可以将数据库查询结果自动缓存起来.
数据缓存的配置, 如上面例子所示 cache组建即可
数据库连接组件中, 需要增加两个与查询缓存相关的配置:
-
yii\db\Connection::queryCacheDuration: 查询结果在缓存中的有效期,以秒表示。如果在调用 yii\db\Connection::beginCache() 时传递了一个显式的时值参数,则配置中的有效期时值会被覆盖。
-
yii\db\Connection::queryCache: 缓存应用组件的 ID。默认为
'cache'
。只有在设置了一个有效的缓存应用组件时,查询缓存才会有效。
配置完毕后, 就可以在执行SQL前开启缓存, 执行后记录缓存了. 语法如下, 通常是在模型中完成
$duration = 60; // 缓存查询结果60秒
$dependency = ...; // 可选的缓存依赖
$db->beginCache($duration, $dependency);
// ...这儿执行数据库查询...
$db->endCache();
这样执行的SQL的结果就会被缓存起来. 自动完成!
页面缓存
页面缓存是将响应的HTML页面, 缓存起来. 之后再访问相同功能页面(动作)时, 就可以直接从缓存中取出HTML, 直接响应!
yii2中使用过滤器(yii\filters\PageCache)机制, 实现的页面缓存的.
由于是过滤器, 因此需要在控制器中, 重写behaviors()方法来定义页面缓存过滤器的使用, 如下代码:
针对index动作, 使用页面缓存, 缓存基于语言而变化, 同时如果缓存的数据源改动, 缓存重写生成!
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',
],
],
];
}
上面的代码, 就是较完整的页面缓存的配置了. 其中:
class, only 都是典型的过滤器选项, 表示过滤器类型和针对的动作.
variations, 表示该页面缓存会基于什么而变化, 本例中, 是依据语言而变化. 这个选项是页面缓存过滤器的独有配置,
dependency, 表示页面缓存的数据依赖, 如果SQL的查询结果变化, 则页面缓存失效. 需要重生成, 也是页面缓存过滤器独有配置.
配置完毕后, 常规使用控制器动作即可, 就可以自动缓存HTML代码!
页面片段缓存
片段缓存指的是缓存页面内容中的某个片段.
片段缓存有部件实现, 因此可以直接在视图模板中使用.
下是在view模板中使用代码.
<?php
$dependency = [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT MAX(updated_at) FROM post',
];
if ($this->beginCache($id, [
'enabled' => Yii::$app->request->isGet,
'duration' => 3600,
'dependency' => $dependency,
'variations' => [Yii::$app->language]
]
)):?>
// ... 在此生成内容 ...
<?php
$this->endCache();
endIf;?>
上面代码展示了典型的片段缓存的用法, 与常规的选项. 其中
-
yii\base\View::beginCache() 和 yii\base\View::endCache() 方法包裹内容生成逻辑。如果缓存中存在该内容,yii\base\View::beginCache() 方法将渲染内容并返回 false,因此将跳过内容生成逻辑。否则,内容生成逻辑被执行,一直执行到 yii\base\View::endCache() 时,生成的内容将被捕获并存储在缓存中。
-
$id, 片段缓存的唯一标志
-
duration, 过期时间时间选项.
-
dependency, 依赖, 类似上节中的页面缓存, 片段也可以设置依赖.
-
variations, 变化量, 类似上节中的页面缓存, 片段也可以设置变化量.
-
enabled, 开关, 可以根据条件选择是否开启片段缓存.
同样, 只要调用了视图对象的$view的beginCache()和endCache()方法, 就可以使用片段缓存了.
HTTP缓存
除了服务器端缓存外, Yii2也支持HTTP缓存. HTTP缓存是通过设置响应头完成, Yii2中, 使用过滤器yii\filters\HttpCache实现的.
同样是过滤器, 因此配置方式与页面缓存一样, 在控制器的behaviors()中:
public function behaviors(){
return [
[
'class' => 'yii\filters\HttpCache',
'only' => ['view'],
'lastModified' => function ($action, $params) {
$q = new \yii\db\Query();
return $q->from('post')->max('updated_at');
},
'etagSeed' => function ($action, $params) {
$post = $this->findModel(\Yii::$app->request->get('id'));
return serialize([$post->title, $post->content]);
},
'cacheControlHeader': 'public, max-age=3600',
],
];
}
以上的代码,就是完整的HTTP缓存的配置. 其中:
-
class, only表示过滤器类和针对的方法
-
lastModified, Last-Modified 头
-
etagSeed, ETag 头
-
cacheControlHeader, Cache-Control 头
配置了HttpCache过滤器后, 就可以根据配置的逻辑, 去设置对于的缓存控制响应头了.
具体的响应头的含义, 请参考 HTTP相关说明
结语
Yii2对缓存的支持, 就这么多了.
欢迎讨论, 拍砖, 一家之言!
最新的文章, 请关注 "小韩说理" 微信公众号. 或者扫描图片上的二维码即可.
如果可以, 请帮忙推荐给你周围需要的朋友!
我的微信QQ: 540090808, 如果需要可以联系我.