Widget 是 Yii 框架中用于处理页面上通用片段的一种机制, 比如一个同类文章推荐, 虽然数据不一样, 但是功能一样, 这样就可以通过不同的参数提交来提高代码的乃至HTML片段的复用度.
同时 Yii 也自带了缓存机制, 用于实现缓存机制.
而我遇到的实际的情况是, 很多 Widget 需要用到缓存机制, 而如果使用了 Memcache, 单个缓存条目是有1M大小限制的, 因此可能需要使用文件缓存, 那么就需要灵活使用cache方式.
至此就做了如下缓存的Widget.
<?php
/**
* 自带 Cache 的 Widget
*/
class CacheWidget extends CWidget {
/**
* 调用的 Cache Id
* @var string
*/
protected $cacheID = 'fcache';
/**
* 缓存的 CacheName
* @var string
*/
protected $cacheName = '';
/**
* 缓存周期
* @var integer
*/
protected $duration = 0;
/**
* 执行Run
*/
public final function run() {
$cacheName = $this->cacheName;
$duration = $this->duration;
$cacheID = $this->cacheID;
if($this->beginCache($cacheName, array(
'duration'=>$duration,
'cacheID'=>$cacheID
))) {
$this->runCache();
$this->endCache();
}
}
/**
* 实际执行的cache部分
*/
public function runCache() {
throw new CExcption('Method `runCache` must be override in class `CacheWidget`.');
}
}
CacheWidget 继承自 CWidget 继承了 Yii Widget 的大多数功能.
cacheId
确定了可调用的 cache 实例, 在当前的配置下, 我默认使用的 Yii::app()->cache 是 Memcache 而 Yii::app()->fcache 是文件缓存.
cacheName
确定了 cache 的名称, 用于开发者定义 cache 的名字.
duration
确定了 cache 的过期时间, 用于开发者自定义 cache 的过期时间
重写父类 CWidget::run() 方法, 并增加 final 特性. run() 方法是 CWidget 被调用时自动执行的方法, 重写该方法就可以重新定义 run 的执行方式, 定义为 final 是避免开发者继承该类后却习惯性的重写了此方法来实现组件. run()方法完成了Cache的处理过程, 为了便于开发者可以方便的使用此类, 于是对外定义了一个新的方法 runCache() 用于实际执行操作.
再新定义一个 runCache() 方法默认抛出异常, 是强制提醒开发者重写此方法的一种约束.
自此, 一个基于 CWidget 的缓存组件类就开发完成了.
最后附上, CacheWidget 的调用方法:
<?php
class MyWidget extends CacheWidget {
/**
* 调用的 Cache Id
* @var string
*/
protected $cacheID = 'cache';
/**
* 缓存的 CacheName
* @var string
*/
protected $cacheName = 'widget.demo';
/**
* 缓存周期
* @var integer
*/
protected $duration = 3600;
/**
* 启动cache调用
*/
public function runCache() {
//读取数据
$demos = DemoModel::model()->findSth();
$this->render('myWidget', [
'demos' => $demos,
])
}