//缓存
$cache = Yii::$app->cache;

// 缓存api
// get : 返回缓存数据,如果缓存失效或不存在返回false
// set : 设置一个缓存
// add : 如果缓存中未找到该键,则将制定数据放到缓存中
// multiGet:通过指定多个键,从缓存中取出多项数据
// multiSet:将多项数据存储到缓存中,每项数据对应一个key
// multiAdd:将多项数据存储到缓存中,每项数据对应一个key
// exists:某个缓存是否存在
// delete:删除某个缓存
// flush:删除缓存中所有数据



//1 数据缓存
$data = Yii::$app->cache->get('postCount');
//缓存依赖: 如果count(id)数量变化了,即使没有到过期时间也会更新缓存
/**
* 缓存依赖类
DbDependency : 如果指定的sql语句结果发生变化,则依赖改变将重新缓存
FileDependency:如果文件最后修改时间发生变化,,则依赖改变将重新缓存
ChainedDependency:如果依赖链上任何一个依赖发生变化,则依赖改变将重新缓存
ExpressionDependency:如果指定php表达式结果发生变化,,则依赖改变将重新缓存
GroupDependency:将一项缓存数据标记到组名,你可以通过调用对象的invalidate()一次性将相同u组名的缓存全部设置为失效状态
*/

$dependency = new \yii\caching\DbDependency(['sql'=>'select count(id) from test']);
if($data === false){
$data = Test::find()->count();
Yii::$app->cache->set('testCount',$data,600,$dependency);
}


//2 片段缓存(可以嵌套使用)
$dependency = new DbDependency(['sql'=>'select count(id) from test']);
if($this->beginCache('cacheKey',['duration'=>600],['dependency'=>$dependency])){
echo TagsCloudWidget::widget(['tags'=>$tags]);
$this->endCache();
}
//片段缓存中有少许动态内容变化,可以调用如下方法插入:
$this->renderDyamic('return Yii::$app->user->identity->name;');


//3 页面缓存
//页面缓存类要放在behaviors中
public function behaviors()
{
return [
'pageCache' => [
'class'=>'yii\filters\PageCache',
'only'=>['index'], //指定要缓存的页面(渲染该页面的action,actionIndex)
'duration'=>600, //过期秒数
'variations'=>[ //让缓存跟随参数变化(比如我缓存一个列表,如果不设置跟随页数变化缓存,那我点第几页都显示第1页缓存,他不会根据参数变化)
Yii::$app->request->get('page'), //设置index列表根据参数页码变化,这样每个页面都有自己的缓存,不会出现每个页都显示第一页的缓存
Yii::$app->request->get('searchKey') //搜索字段使用不同缓存
],
'dependency'=>[ //依赖
'class'=>'yii\caching\DbDependency',
'sql'=>'select count(id) from test'
]
],
];
}


//4 http缓存
//http缓存与页面缓存同样配置在behaviors中
public function behaviors()
{
return [
'httpCache' => [
'class'=>'yii\filters\HttpCache',
'only'=>['detail'], //指定要缓存的页面(渲染该页面的action,actionIndex)

//可以设置三种http的header:lastModified,etagSeed,cacheControlHeader
'lastModified'=>function($action,$params){ //对应http头的Last-Modified,会给http头设置一个时间,如果这个时间修改了就重新请求
$q = new \yii\db\Query();
return $q->from('test')->max('update_time');
},
'etagSeed'=>function($action,$param){ //对应http头的Etag,会给http头设置一个hash值,如果这个hash值修改了就重新请求
$test = Test::findOne(Yii::$app->request->get('id'));
return serialize($test);
},
'cacheControlHeader'=>'public,max-age=600' //对应http头的Cache-Control,默认600s

],
];
}