页面静态缓存指的是缓存整个页面的内容,下一次请求的时候直接返回静态页面,以提高程序性能。
# 关键问题
- 在Yii1.1中如何配置实现页面静态缓存
- 静态页面缓存后,页面局部内容动态化,如当前登录用户名、文章查看次数等
- 当内容有更新后,静态页面如何实时更新,而不用等静态缓存到过期后才更新
# 页面静态缓存配置
- 在
protected/config/main.php
添加cache组件
<?php
array(
......
'components'=>array(
......
'cache'=>array(
'class'=>'system.caching.CFileCache',
'directoryLevel'=>2,
),
),
);
- 在控制器中新增filter
protected/controllers/PostController.php
<?php
class PostController extends Controller
{
/**
* @return array action filters
*/
public function filters()
{
return array(
array(
'COutputCache + index',
'duration'=>60,
),
array(
'COutputCache + view',
'duration'=>60,
'varyByParam'=>array('id'),
),
);
}
}
现在post/index
和post/view?id=xxx
页面就实现了页面静态缓存60秒
# 页面局部动态化
# 在文章列表新增【当前用户】和【当前时间】
protected/views/post/index.php
...别的HTML内容...
<p>当前用户;<?= $this->renderDynamic('OutputDynamic::currentUser') ?></p>
<p>当前时间;<?= $this->renderDynamic('OutputDynamic::currentTime') ?></p>
...别的HTML内容...
protected/components/OutputDynamic.php
<?php
class OutputDynamic
{
public static function currentUser()
{
if (Yii::app()->user->isGuest) {
return CHtml::link('未登录,点击登录', array('/user/login'));
}
return CHtml::link(Yii::app()->user->name, array('/user/center')) . ',' . CHtml::link('点击退出', array('/user/logout'));
}
public static function currentTime()
{
return date('Y-m-d H:i:s');
}
}
# 在文章详情中新增【查看次数】
protected/views/post/view.php
...别的HTML内容...
<p>查看次数;<?= $this->renderDynamic('OutputDynamic::viewCount', array('id' => $model->id)) ?></p>
...别的HTML内容...
protected/components/OutputDynamic.php
<?php
class OutputDynamic
{
...别的PHP内容
public static function viewCount($params)
{
$model = Post::model()->findByPk($params['id'], array('select'=>'id,count'));
if (!$model) {
return 0;
}
$model->count++;
$model->update();
return $model->count;
}
}
# 页面实时更新
将filter修改一下,以实现如下效果:
- 当有文章新增或更新后,文章列表的静态缓存将失效。
- 当有文章更新后,文章详情的静态缓存将失效。
protected/controllers/PostController.php
<?php
class PostController extends Controller
{
/**
* @return array action filters
*/
public function filters()
{
return array(
array(
'COutputCache + index',
'duration'=>60,
'dependency'=>array(
'class'=>'CDbCacheDependency',
'sql'=>'SELECT MAX(update_time) FROM {{post}}',
)
),
array(
'COutputCache + view',
'duration'=>60,
'varyByParam'=>array('id'),
'dependency'=>array(
'class'=>'CDbCacheDependency',
'sql'=>'SELECT update_time FROM {{post}} WHERE id=:id LIMIT 1',
'params'=>array(':id'=>Yii::app()->request->getQuery('id')),
)
),
);
}
}
当然也可以使用其他的缓存依赖类来实现,常用缓存依赖类:
- 文件缓存依赖:CFileCacheDependency,使用
touch()
函数来更新文件 - 数据库缓存依赖:CDbCacheDependency
- 表达式依赖:CExpressionDependency
# 实现原理
- 静态缓存原理
使用ob_start()
、ob_get_clean()
等函数获取渲染内容,然后缓存起来
- 局部动态原理
在静态文件中打标记,然后再用动态内容替换掉,生成的静态文件如下:
...别的HTML内容...
<p>当前用户;<###dynamic-0###></p>
<p>当前时间;<###dynamic-1###></p>
...别的HTML内容...
静态缓存文件中同时还缓存了标记处的函数调用名称,以及函数需要传递的参数,在读取静态缓存后,使用函数调用的返回值将标记替换掉。
- 实时更新原理
静态缓存文件中还缓存了【缓存依赖】相关的信息(当前标记、如何获取标记),用于获取最新的标记,当标记发送变化后将视为缓存失效。
# 参考
🕑 最后更新时间: 2022-09-24 16:24