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, ]) }