Yii1.1中页面静态缓存的应用

9/24/2022 Yii

页面静态缓存指的是缓存整个页面的内容,下一次请求的时候直接返回静态页面,以提高程序性能。

# 关键问题

  1. 在Yii1.1中如何配置实现页面静态缓存
  2. 静态页面缓存后,页面局部内容动态化,如当前登录用户名、文章查看次数等
  3. 当内容有更新后,静态页面如何实时更新,而不用等静态缓存到过期后才更新

# 页面静态缓存配置

  1. protected/config/main.php添加cache组件
<?php
array(
    ......
    'components'=>array(
        ......
        'cache'=>array(
            'class'=>'system.caching.CFileCache',
			'directoryLevel'=>2,
        ),
    ),
);
  1. 在控制器中新增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/indexpost/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修改一下,以实现如下效果:

  1. 当有文章新增或更新后,文章列表的静态缓存将失效。
  2. 当有文章更新后,文章详情的静态缓存将失效。

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

# 实现原理

  1. 静态缓存原理

使用ob_start()ob_get_clean()等函数获取渲染内容,然后缓存起来

  1. 局部动态原理

在静态文件中打标记,然后再用动态内容替换掉,生成的静态文件如下:

...别的HTML内容...
<p>当前用户;<###dynamic-0###></p>
<p>当前时间;<###dynamic-1###></p>
...别的HTML内容...

静态缓存文件中同时还缓存了标记处的函数调用名称,以及函数需要传递的参数,在读取静态缓存后,使用函数调用的返回值将标记替换掉。

  1. 实时更新原理

静态缓存文件中还缓存了【缓存依赖】相关的信息(当前标记、如何获取标记),用于获取最新的标记,当标记发送变化后将视为缓存失效。

# 参考

🕑 最后更新时间: 2022-09-24 16:24