yii框架缓存知识总结(转载)

缓存是用于提升网站性能的一种即简单又有效的途径。稍微有点规模的网站都会通过存储相对静态的数据至缓存以备所需,这样我们可以省去从数据库查询然后生成这些数据的时间,通过减轻数据库的压力从而提升网站的性能。

Yii作为一个强大的php开源框架,再缓存这块,YII对各种流行的缓存都提供了接口,我们可以根据实际的需要使用不同的缓存。

yii的缓存相关组件存放在yii/framework/caching的目录内,通过查看该目录,我们可以知道yii所支持的都有哪些缓存。下面我们对相关文件做一些简单的介绍:

CMemCache: 使用 PHP memcache 扩展.

CApcCache: 使用 PHP APC 扩展.

CXCache: 使用 PHP XCache 扩展。注意,这个是从 1.0.1 版本开始支持的。

CEAcceleratorCache: 使用 PHP EAccelerator 扩展.

CDbCache: 使用一个数据表存储缓存数据。默认情况下,它将创建并使用在 runtime 目录下的一个 SQLite3 数据库。 你也可以通过设置其 connectionID 属性指定一个给它使用的数据库。

CZendDataCache: 使用 Zend Data Cache 作为后台缓存媒介。注意,这个是从 1.0.4 版本开始支持的。

CFileCache: 使用文件存储缓存数据。这个特别适合用于存储大块数据(例如页面)。注意,这个是从 1.0.6 版本开始支持的。

CDummyCache: 目前 dummy 缓存并不实现缓存功能。此组件的目的是用于简化那些需要检查缓存可用性的代码。例如,在开发阶段或者服务器尚未支持实际的缓存功能,我们可以使用此缓存组件。当启用了实际的缓存支持后,我们可以切换到使用相应的缓存组件。在这两种情况中,我们可以使用同样的代码Yii::app()->cache->get($key) 获取数据片段而不需要担心 Yii::app()->cache 可能会是 null。此组件从 1.0.5 版开始支持。

提示: 由于所有的这些缓存组件均继承自同样的基类 CCache,因此无需改变使用缓存的那些代码就可以切换到使用另一种缓存方式。

在 Yii 中使用缓存主要包括配置和访问缓存组件 。 下面以分别以使用 memcache 缓存组件和文件缓存组件为例做二个说明:

(1)memcache 缓存示例:

如下的应用配置指定了一个使用两台缓存服务器的 memcache 缓存组件:

查看代码

打印

01 array(
02     ......
03     ‘components‘=>array(
04         ......
05         ‘phpernote_cache‘=>array(
06             ‘class‘=>‘system.caching.CMemCache‘,
07             ‘servers‘=>array(
08                 array(‘host‘=>‘10.201.1.101‘‘port‘=>11211, ‘weight‘=>60),
09                 array(‘host‘=>‘10.201.1.102‘‘port‘=>11211, ‘weight‘=>40),
10             ),
11         ),
12     ),
13 );

程序运行的时候可以再控制器方法中通过 Yii::app()->phpernote_cache 来访问缓存组件,例如:

Yii::app ()->phpernote_cache->set($key,$value,$expire);

Yii::app()->phpernote_cache->add($id,$value);

Yii::app ()->phpernote_cache->get($key);

(2)文件缓存示例:

1. 在config文件加入缓存配置信息

查看代码

打印

01 array(
02     ......
03     ‘components‘=>array(
04         ......
05         ‘cache‘=>array(
06             ‘class‘=>‘system.caching.CFileCache‘,
07             ‘directoryLevel‘=>2
08             ),
09         ),
10     ),
11 );

以上配置中 directoryLevel 设置的是缓存文件的目录深度;如果缓存页面特别多,这个值需要设置大点,否则每个目录下的页面会很多。

2. 在要做缓存的控制器里定义过滤器。

查看代码

打印

01 public function filters(){
02     return array(
03         array(
04             ‘COutputCache + post, list‘,
05             ‘duration‘=>3600,
06             ‘varyByParam‘=>array(‘id‘,‘page‘),
07             ‘dependency‘=>array(
08             ‘class‘=>‘CDbCacheDependency‘,
09             ‘sql‘=>‘SELECT MAX(id) FROM phpernote_article‘,
10         )
11     );
12 }

COutputCache 是用于处理缓存的类,如果只填‘COutputCache‘,则控制器里所有action都会通过缓存过滤,定义‘COutputCache + post, list‘,表示只对以下方法进行缓存:actionPost, actionList 。

duration 是缓存的时间,单位是秒,

varyByParam 是指定一系列GET参数名称列表, 使用相应的值去确定缓存内容的版本,即同一个action用于区分是不同页面的的参数,此处我以id和page来区分不同页面。

除varyByParam以外,还可以采用其他的条件来区分页面:

varyByExpression:指定缓存内容通过自定义的PHP表达式的结果而变化

varyByRoute:指定缓存内容基于请求的路由不同而变化 (controller 和 action)

varyBySession:指定是否缓存内容. 因用户session不同而变化

dependency‘指定缓存失效依赖关系:可指定文件或数据库;本示例指定的是数据库依赖 CDbCacheDependency ,通过数据表的某个值的变化来确定缓存是否失效。例如,如果在表中新增了一条记录,即使缓存才过了5分钟(<3600),仍然判断为失效,从而查询数据库,生成整个页面,再次缓存;
   
提示:yii也可以支持Redis,需要装一个插件:http://www.yiibase.com/download/view/32.html

缓存可以在不同的级别使用。在最低级别,可用来缓存单个数据(数据缓存)。往上一级,我们缓存一个由视图脚本生成的页面片断(片段缓存)。在最高级别,可存储整个页面以便需要的时候直接从缓存读取。本文说明页面缓存的配置及实现效果;

数据缓存

数据缓存即存储一些 PHP 变量到缓存中,以后再从缓存中取出来。出于此目的,缓存组件的基类 CCache 提供了两个最常用的方法: set() 和 get()。

要在缓存中存储一个变量 $value ,我们选择一个唯一 ID 并调用 set() 存储它:

Yii::app()->cache->set($id, $value);缓存的数据将一直留在缓存中,除非它由于某些缓存策略(例如缓存空间已满,旧的数据被删除)而被清除。 要改变这种行为,我们可以在调用 set() 的同时提供一个过期参数,这样在设定的时间段之后,缓存数据将被清除:

// 值$value 在缓存中最多保留30秒
Yii::app()->cache->set($id, $value, 30);稍后当我们需要访问此变量时(在同一个或不同的 Web 请求中),就可以通过 ID 调用 get() 从缓存中将其取回。 如果返回的是 false,表示此值在缓存中不可用,我们应该重新生成它。

查看代码

打印

1 $value=Yii::app()->cache->get($id);
2 if($value===false){
3     // 因为在缓存中没找到 $value ,重新生成它 ,
4     // 并将它存入缓存以备以后使用:
5     // Yii::app()->cache->set($id,$value);
6 }

为要存入缓存的变量选择 ID 时,要确保此 ID 对应用中所有其他存入缓存的变量是唯一的。而在不同的应用之间,这个 ID 不需要是唯一的。缓存组件具有足够的智慧区分不同应用中的 ID。

一些缓存存储器,例如 MemCache, APC, 支持以批量模式获取多个缓存值。这可以减少获取缓存数据时带来的开销。从版本 1.0.8 起,Yii 提供了一个新的名为 mget() 的方法。它可以利用此功能。如果底层缓存存储器不支持此功能,mget() 依然可以模拟实现它。

要从缓存中清除一个缓存值,调用 delete(); 要清楚缓存中的所有数据,调用 flush()。 当调用 flush() 时一定要小心,因为它会同时清除其他应用中的缓存。

提示: 由于 CCache 实现了 ArrayAccess,因此缓存组件也可以像一个数组一样使用。下面是几个例子:

查看代码

打印

1 $cache=Yii::app()->cache;
2 $cache[‘username‘]=$value1;  // 相当于: $cache->set(‘username‘,$value1);
3 $value2=$cache[‘username‘];  // 相当于: $value2=$cache->get(‘username‘);

1. 缓存依赖

除了过期设置,缓存数据也可能会因为依赖条件发生变化而失效。例如,如果我们缓存了某些文件的内容,而这些文件发生了改变,我们就应该让缓存的数据失效,并从文件中读取最新内容而不是从缓存中读取。

我们将一个依赖关系表现为一个 CCacheDependency 或其子类的实例。 当调用 set() 时,我们连同要缓存的数据将其一同传入。如下面这段代码的意思就是此值将在30秒后失效,但如果依赖的文件发生了变化则立即失效:
 
Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency(‘FileName‘));

现在如果我们通过调用get() 从缓存中获取 $value ,依赖关系将被检查,如果发生改变,我们将会得到一个 false 值,表示数据需要被重新生成。

如下是可用的缓存依赖的简要说明:

CFileCacheDependency: 如果文件的最后修改时间发生改变,则依赖改变。

CDirectoryCacheDependency: 如果目录和其子目录中的文件发生改变,则依赖改变。

CDbCacheDependency: 如果指定 SQL 语句的查询结果发生改变,则依赖改变。

CGlobalStateCacheDependency: 如果指定的全局状态发生改变,则依赖改变。全局状态是应用中的一个跨请求,跨会话的变量。它是通过 CApplication::setGlobalState() 定义的。

CChainedCacheDependency: 如果链中的任何依赖发生改变,则此依赖改变。

CExpressionDependency: 如果指定的 PHP 表达式的结果发生改变,则依赖改变。此类从版本 1.0.4 起可用。

片段缓存(Fragment Caching)

片段缓存指缓存网页某片段。例如,如果一个页面在表中显示每年的销售摘要,我们可以存储此表在缓存中,减少每次请求需要重新产生的时间。

要使用片段缓存,在控制器视图脚本中调用 CController::beginCache() 和 CController::endCache() 。这两种方法开始和结束包括的页面内容将被缓存。类似data caching ,我们需要一个编号,识别被缓存的片段。例如下面这段代码如果beginCache() 返回false,缓存的内容将此地方自动插入; 否则,在if语句内的内容将被执行并在endCache()触发时缓存。

查看代码

打印

1 ......
2 <?php if($this->beginCache($id)) { ?>
3 ...被缓存的内容...
4 <?php $this->endCache(); } ?>
5 ......

1. 缓存选项(Caching Options)

当调用beginCache(),可以提供一个数组由缓存选项组成的作为第二个参数,以自定义片段缓存。事实上为了方便,beginCache() 和endCache()方法是[ COutputCache ]widget的包装。因此COutputCache的所有属性都可以在缓存选项中初始化。

有效期(Duration)

也许是最常见的选项是duration,指定了内容在缓存中多久有效。和CCache::set()过期参数有点类似。下面的代码缓存内容片段最多一小时:

查看代码

打印

1 ......
2 <?php if($this->beginCache($idarray(‘duration‘=>3600))) { ?>
3 ...被缓存的内容...
4 <?php $this->endCache(); } ?>
5 ......

如果我们不设定期限,它将默认为60 ,这意味着60秒后缓存内容将无效。

依赖(Dependency)

像data caching ,内容片段被缓存也可以有依赖。例如,文章的内容被显示取决于文章是否被修改。

要指定一个依赖,我们建立了dependency选项,可以是一个实现[ICacheDependency]的对象或可用于生成依赖对象的配置数组。下面的代码指定片段内容取决于lastModified 列的值是否变化:

查看代码

打印

1 ......
2 <?php if($this->beginCache($idarray(‘dependency‘=>array(
3         ‘class‘=>‘system.caching.dependencies.CDbCacheDependency‘,
4         ‘sql‘=>‘SELECT MAX(lastModified) FROM Post‘)))) { ?>
5 ...被缓存的内容...
6 <?php $this->endCache(); } ?>
7 ......

变化(Variation)

缓存的内容可根据一些参数变化。例如,每个人的档案都不一样。缓存的档案内容将根据每个人ID变化。这意味着,当调用beginCache()时将用不同的ID。

COutputCache内置了这一特征,程序员不需要编写根据ID变动内容的模式。以下是摘要。

varyByRoute: 设置此选项为true ,缓存的内容将根据route变化。因此,每个控制器和行动的组合将有一个单独的缓存内容。

varyBySession: 设置此选项为true ,缓存的内容将根据session ID变化。因此,每个用户会话可能会看到由缓存提供的不同内容。

varyByParam: 设置此选项的数组里的名字,缓存的内容将根据GET参数的值变动。例如,如果一个页面显示文章的内容根据id的GET参数,我们可以指定varyByParam为array(‘id‘),以使我们能够缓存每篇文章内容。如果没有这样的变化,我们只能能够缓存某一文章。

有时候,我们希望片段缓存只对某些类型的请求启用。例如,对于某张网页上显示表单,我们只想要缓存initially requested表单(通过GET请求)。任何随后显示(通过POST请求)的表单将不被缓存,因为表单可能包含用户输入。要做到这一点,我们可以指定 requestTypes 选项:

查看代码

打印

1 ......
2 <?php if($this->beginCache($idarray(‘requestTypes‘=>array(‘GET‘)))) { ?>
3 ...被缓存的内容...
4 <?php $this->endCache(); } ?>
5 ......

2. 嵌套缓存(Nested Caching)

片段缓存可以嵌套。就是说一个缓存片段附在一个更大的片段缓存里。例如,意见缓存在内部片段缓存,而且它们一起在外部缓存中在文章内容里缓存。

查看代码

打印

1 ......
2 <?php if($this->beginCache($id1)) { ?>
3 ...外部被缓存内容...
4     <?php if($this->beginCache($id2)) { ?>
5     ...内部被缓存内容...
6     <?php $this->endCache(); } ?>
7 ...外部被缓存内容...
8 <?php $this->endCache(); } ?>
9 ......

嵌套缓存可以设定不同的缓存选项。例如,在上面的例子中内部缓存和外部缓存可以设置时间长短不同的持续值。当数据存储在外部缓存无效,内部缓存仍然可以提供有效的内部片段。然而,反之就不行了。如果外部缓存包含有效的数据, 它会永远保持缓存副本,即使内容中的内部缓存已经过期。

页面缓存

页面缓存指的是缓存整个页面的内容。页面缓存可以发生在不同的地方。例如,通过选择适当的页面头,客户端的浏览器可能会缓存网页浏览有限时间。Web应用程序本身也可以在缓存中存储网页内容。 在本节中,我们侧重于后一种办法。

页面缓存可以被看作是 片段缓存一个特殊情况 。 由于网页内容是往往通过应用布局来生成,如果我们只是简单的在布局中调用beginCache() 和endCache(),将无法正常工作。这是因为布局在CController::render()方法里的加载是在页面内容产生之后。

如果想要缓存整个页面,我们应该跳过产生网页内容的动作执行。我们可以使用COutputCache作为动作 过滤器来完成这一任务。下面的代码演示如何配置缓存过滤器:

查看代码

打印

1 public function filters(){
2     return array(
3         array(
4             ‘COutputCache‘,
5             ‘duration‘=>100,
6             ‘varyByParam‘=>array(‘id‘),
7         ),
8     );
9 }

上述过滤器配置会使过滤器适用于控制器中的所有行动。 我们可能会限制它在一个或几个行动通过使用插件操作器。 更多的细节中可以看过滤器。

提示: 我们可以使用COutputCache作为一个过滤器,因为它从CFilterWidget继承过来, 这意味着它是一个工具(widget)和一个过滤器。事实上,widget的工作方式和过滤器非常相似。工具widget (过滤器filter)是在action动作里的内容执行前执行,在执行后结束。

6.缓存的使用:动态内容(Dynamic Content)

当使用fragment caching或page caching,我们常常遇到的这样的情况 整个部分的输出除了个别地方都是静态的。例如,帮助页可能会显示静态的帮助 信息,而用户名称显示的是当前用户的。

解决这个问题,我们可以根据用户名匹配缓存内容,但是这将是我们宝贵空间一个巨大的浪费,因为缓存除了用户名其他大部分内容是相同的。我们还可以把网页切成几个片段并分别缓存,但这种情况会使页面和代码变得非常复杂。更好的方法是使用由[ CController ]提供的动态内容dynamic content功能 。

动态内容是指片段输出即使是在片段缓存包括的内容中也不会被缓存。即使是包括的内容是从缓存中取出,为了使动态内容在所有时间是动态的,每次都得重新生成。出于这个原因,我们要求 动态内容通过一些方法或函数生成。

调用CController::renderDynamic()在你想的地方插入动态内容。

查看代码

打印

1 ......
2 <?php if($this->beginCache($id)) { ?>
3 ...被缓存的片段内容...
4     <?php $this->renderDynamic($callback); ?>
5 ...被缓存的片段内容...
6 <?php $this->endCache(); } ?>
7 ......

在上面的,$callback指的是有效的PHP回调。它可以是指向当前控制器类的方法或者全局函数的字符串名。也可以是一个数组名指向一个类的方法。其他任何的参数,将传递到 renderDynamic()方法中。回调将返回动态内容而不是仅仅显示它。

时间: 2024-11-03 22:08:51

yii框架缓存知识总结(转载)的相关文章

Yii框架分布式缓存的实现方案

声明:本文阅读对象最好是对Yii和分布式缓存有一定了解的人群,否则理解和掌握上有一些困难,建议阅读之前做好以上两点基础准备. YiiFramework简称Yii,读作易,代表简单(easy).高效(efficient).可扩展(extensible),Yii将面向对象思想以及代码的重用性发挥到了极致,尤其是在缓存的支持上,Yii是最有效率的PHP框架之一. Yii的缓存支持封装在框架核心的caching文件夹下面,如下图是Yii支持的缓存存储介质. 如果要做跨Session和请求的分布式缓存,可

YII框架——数据缓存

YII框架——数据缓存 YII缓存的配置: YII目录/config/web.php文件,配置cache数组下,class数组的值,默认为yii\caching\FileCache. 2.缓存的使用:获取缓存组件: $cache=\YII::$app->cache; 添加缓存数据: $cach->add(key,value[,time][,dependency]); 参数: Key 键   Value 值   Time 可选,缓存有效期   Dependency 可选,依赖方式 返回值:  

Yii框架下使用redis做缓存,读写分离

Yii框架中内置好几个缓存类,其中有memcache的类,但是没有redis缓存类,由于项目中需要做主从架构,所以扩展了一下: /** * FileName:RedisCluster * 配置说明 * 配置为1主多从 或者 1个独立的服务器 * 写往主的里面写 * 读是从从的里面读 * 'class'=>'RedisCache', * 'servers'=>array( * array( * 'host'=>'IP1', * 'port'=>'6380', * 'master'=&

与《YII框架》不得不说的故事—5篇目录

与<YII框架>不得不说的故事—基础篇 第1章 课程目标 1-1 课程目标 (00:54) 第2章 课前知识准备 2-1 YII的启动和安装 (05:12) 2-2 YII请求处理流程 (02:44) 2-3 命名空间 (10:46) 第3章 控制器 3-1 控制器的创建 (03:22) 3-2 控制器之请求处理 (05:58) 3-3 控制器之响应处理 (09:09) 3-4 控制器之session处理 (09:25) 3-5 控制器之cookie处理 (09:11) 第4章 视图 4-1

Yii框架官方教程增补篇1——开始:Yii是什么

Yii 是一个基于组件的高性能 PHP 框架,用于快速开发大型 Web 应用.它使Web开发中的可复用度最大化,可以显著提高你的Web应用开发速度.Yii 这个名字(读作易(Yee) 或 [ji:])是"Yes It Is!"的缩写.这往往是对于一些经常被问到的问题的最准确的答案: Yii快不快?安全吗?专业吗?是否适用于我的下一个项目?Yes, it is! Yii框架作者薛强同时也是Prado Framework的作者,在编写Yii框架的过程中,作者最大化借鉴了Prado,Ruby

Yii 框架创建自己的 web 应用

本篇文章转载自http://www.ibm.com/developerworks/cn/opensource/os-cn-yii/ Yii 是当今国内外最为流行的 PHP 框架.由于它高性能的特性,被公认为是“最有效率的 PHP 框架”.Yii 提供了今日 Web 2.0 应用开发所需要的几乎一切功能.它可以通过一个简单的命令 yiic 来快速创建一个 Web 应用程序的代码框架,开发人员通过在生成的代码框架上编写自己的业务逻辑,来实现 Web 应用的快速开发.本文将通过具体的实例对 Yii 框

ThinkPHP框架基本知识,介绍给新人

tp基础框架基本知识 thinkPHP框架简称TP框架: index.php:项目的入口文件,所有的页面都从这个页面进入application:存放项目的文件夹public:存放公有的东西thinkPHP:TP框架的核心文件夹,里面的东西尽量不要修改里面包含:1.common:核心函数库,用户自定义的函数可以存在这里面2.conf:配置文件,主要在里面的convention.php3.lang:语言包4.library:存放TP核心类文件,里面的think存放类,我们使用的类基本都在5.mode

Yii框架配置

1.将yii框架命令行工具yiic.bat的路径加入环境变量,以便可以使用CMD命令创建项目 2.创建项目: framework是yii的核心,尽量保持核心包的完整性以后创建多个项目时可以共用,在framework同级的目录创建一个自己的项目文件夹,如:webapp CMD创建项目:>yiic webapp ../webapp/myblog(因为配置的环境变量是在framework下,故返回上层找webapp) 尊重原创,转载请保留:(Yii框架配置)http://www.cnblogs.com

YII框架分析笔记5:控制器和动作

CBaseController是控制器和挂件的基类,主要提供了视图渲染,挂件,剪辑.片段缓存等方法,CController是所有应用中自定义控制器的基类. 创建动作 [php] view plaincopy public function run($actionID) { if(($action=$this->createAction($actionID))!==null) { if(($parent=$this->getModule())===null) $parent=Yii::app()