YII缓存依赖的应用
缓存是提升Web应用性能的简便有效的方式。当我们在加载网页需要过多的时间,比如说查询时间过久,抑或是调用接口占用过多I/O,建立缓存是一个行之有效的方法,它可以避免多次加载页面缓慢的不良用户体验。但是网页中数据并不是一成不变的,它是变化的,就如查询有不同条件不同内容,所以我们缓存的内容也要随之变化,这就是缓存依赖所存在的必要性。
设置缓存
一般情况下,我们会给缓存的变量设置过期时间,到了过期时间,该变量也就随之有效,下次加载就必须重新生成缓存,这就是一种依赖条件,设置过期时间。
- // 变量将在30秒后失效
- Yii::app()->cache->set($id, $value, 30 ) ;
而缓存依赖的条件不会只是这么单一,它可以依赖文件内容、数据库、表达式、php中的全局变量。
YII使用缓存依赖
上述是我在工作中的理解,相信大家有过做静态页面的也会有这种因变而变的方式。下面描述具体的实现(在这里提及下我用的是Yii1.1):
1、在应用config文件components(组件配置) 加入缓存组件.
- 'components'=>array(
- ...
- 'cache' => array (
- 'class' => 'system.caching.CFileCache', #方式 文件缓存 缓存方式有 [CMemCache]: 使用 PHP memcache 扩展.[CApcCache]: 使用 PHP APC 扩展.等等,具体参考Yii社区文档。
- 'directoryLevel' => 2,
- ),
- ...
- )
2、使用缓存依赖条件
-
依赖文件
- #依赖文件
- Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));
依赖文件也很容易理解,比如说程序中会出现对城市的配置存贮文件,可能某个城市或是下级出现多个区,这个文件就会发生改变了,那缓存的这个数据就应该根据依赖条件过期,重新生成这个缓存文件。使用方法可以灵活运用:
- if(!Yii::app()->cache->get('city')){
- Yii::app()->cache->set('city', include('path/city.php'), 30, new CFileCacheDependency('path/city.php'));
- }
- //todo:执行操作
-
依赖SQL
用的广泛的应该是SQL数据的查询依赖
- #依赖SQL
- Yii::app()->cache->set($id, $value, 30, new CDbCacheDependency('SELECT ...'));
举个列子:
在一个数据比较庞大的订单记录中统计时间段内的成交金额,以及利润,在这样的查询页面会产生过多的加载时间,等待是痛苦的。我们可以将查询的结果按时间段存储到缓存中,订单是变化的,统计的时间段一旦涉及今天,则统计需依赖订单的最新创建时间,如创建时间变化,此时缓存失效,可重新生成缓存;反之,缓存不受影响;- /*订单表(order) id uerid price type(订单类型) state(1为已支付 0 未支付) paytime createtime isdelete*/
- #查询成交金额
- function ordercheck($starttime,$endtime){
- $cacheid = "order".$starttime.$endtime; //设置缓存id
- if( !Yii::app()->cache->get($cacheid) ){
- $sql = "SELECT SUM(price) as sumprice FROM order WHERE state=1 AND isdelete=0";
- $addsql = '';
- if( $starttime ) $addsql.=" AND createtime>={$starttime}";
- if( $endtime ) $addsql.=" AND createtime>={$endtime}";
- $res = Yii::app()->createCommand($sql.$addsql)->queryAll; //开始时间或结束时间大于等于今天时间戳则建立依赖
- $date = date('Y-m-d',time());
- if( $starttime>=strtotime($date) || $endtime>=strtotime($date) ){
- //依赖条件为最新的订单时间发生改变
- $dependency = new CDbCacheDependency('SELECT MAX(createtime) FROM order WHERE state=1 AND isdelete=0');
- Yii::app()->cache->set($cacheid,$res['sumprice'] , 1800,$dependency);
- }else{
- Yii::app()->cache->set($cacheid, $res['sumprice'], 1800);
- }
- }
- return Yii::app()->cache->get($cacheid) ;
- }
-
依赖表达式
- #表达式
- Yii::app()->cache->set($id, $value, 30, new CExpressionDependency( 'yii::app->session(\'automer\')') );
上面的例子当全局的session automer 发生变化,相应的缓存失效。
其他的缓存就不再此介绍了,我觉得重要的是理解缓存及缓存依赖的概念 ,多写些应用场景,就能设计出实用的缓存程序,这对于界面的加载反应时间将提高很多速度。我做过的项目中,有数据都是通过接口获取的,当写一个复杂的逻辑就会调用很多次接口,非常费时,通过缓存数据就不需要再请求接口的时间。有点瑕疵的就是第一次加载是费时的,不过也是可以解决的,如果有个脚本在更新这个缓存,那就不是问题。还有更深入的,缓存依赖管理工具,它将为你管理生成所需的缓存,这里就起一个抛砖引玉的作用,不再深究。Yii也提供很多好的缓存方法,片段缓存,页面缓存,HTTP缓存。。。
挺不错的,在理解的基础上灵活应用也是一大进步。加油各位,加油自己,天行健!