一、Zend_Cache快速浏览
Zend_Cache
提供了一个缓存任何数据的一般方法。
在Zend Framework中缓存由前端操作,同时通过后端适配器(File
,Sqlite
, Memcache
...)和 一个灵活的IDs和Tags系统(标识符和标记系统)存储缓存纪录。
模块(Zend_Cache_Core
) 的核心是通用,灵活和可配置。对于特定的需要,为了便捷,这里有一些继承自Zend_Cache_Core
的前端:Output
、
File、
Function
和Class
。
(1)调用 Zend_Cache::factory()
取得一个前端
$frontendOptions = array ( ' lifeTime ' => 7200 , // 两小时的缓存生命期 ' automatic_serialization ' => true ); $backendOptions = array ( ' cache_dir ' => ' ./tmp/ ' // 放缓存文件的目录 ); // 取得一个Zend_Cache_Core 对象 $cache = Zend_Cache :: factory( ' Core ' , ' File ' , $frontendOptions , $backendOptions );
(2)将从数据库中查询出来的结果缓存起来
现在有了一个前端,可用缓存任何类型的数据了(开了序列化'serialization')。
例如,能够缓存从昂贵的数据库查询中缓存一个结果。结果被缓存后,不再需要连接到数据库;数据直接在缓存中取回和反序列化。
// $cache 在先前的例子中已经初始化了 // 查看一个缓存是否存在: if ( ! $result = $cache -> load( ' myresult ' )) { // 缓存不命中;连接到数据库 $db = Zend_Db :: factory( [ ... ] ); $result = $db -> fetchAll( ' SELECT * FROM huge_table ' ); $cache -> save( $result , ' myresult ' );//利用zend_cache对象缓存查询出来的结果 } else { // 缓存名中,读出缓存到myresult标签中的$result内容 。 echo " This one is from cache!\n\n " ; } print_r ( $result );
(3)用Zend_Cache
前端缓存输出
通过加入条件逻辑,我们'mark up'(标记)那些希望缓存输出的段(sections),在start()
和end()
方法间封装这些section(这类似第一个例子,并且是缓存的核心策略)。
在内部,像往常一样输出你的数据,当执行到end()
方法时,所有之前的输出都被缓存。
在下一次运行时,整个段(end()方法调用前的代码)将被跳过执行,直接从Cache中取回数据(只要缓存纪录是有效的)。
小结:在使用Zend_Cache是特别要注意的Cache标识(传递给//前端操设置cache的存储时间,以及是否序列化对象 $frontendOptions = array ( ' lifeTime ' => 30 , // cache lifetime of 30 seconds ' automatic_serialization ' => false // this is the default anyway s ); //后端适配器配置cache的存储路径 $backendOptions = array ( ' cache_dir ' => ' ./tmp/ ' ); $cache = Zend_Cache :: factory( ' Output ' , ' File ' , $frontendOptions , $backendOptions ); // 传递一个唯一标识符给start()方法 if ( ! $cache -> start( ' mypage ' )) { // output as usual: echo ' Hello world! ' ; echo ' This is cached ( ' . time () . ' ) ' ; $cache -> end (); // the output is saved and sent to the browser } echo ' This is never cached ( ' . time () . ' ). ' ;
save()
和start()
的参数).它必须对于你所缓存的每个资源唯一,否则不相关的缓存纪录就会相互覆盖, 更糟的是,导致错误的显示结果.
二、缓存原理
缓存原理:
在Zend_Cache中有三个关键概念:
一是用于标识缓存纪录的唯一标识符(一个字符串);
二是'lifeTime'
指令,正如例子中所见,,它定义了缓存纪录的生命期(超过该值,缓存纪录被销毁)。
三是条件执行,你的部分代码可用被跳过,以加速性能。
前端函数(例如 Zend_Cache_Core::get()
)在缓存不命中时返回false,这使用户能处理if(){ ... }
语句中的条件,包含代码中他们所要缓存(或者跳过)的部分最后是否必须保存这些你曾经生成的块(例如:Zend_Cache_Core::save()
)
注意:'缓存命中'是一个术语,它表示当一个缓存纪录发现可用,是有效的并且是'fresh'的(换言之,就是还没有过期)。
'Cache miss' 表示当在缓存中找不到需要的数据时,发生缓存不命中。 当一个Cache miss发生是,,你必须生成你的数据,并使它被缓存。而对于缓存命中,后端自动透明地从Cache中取回缓存纪录。
必须使用Zend_Cache::factory()
来得到前端实例。你自己直接实例化的前端或者后端不能按照期望工作。
(1)Zend_Cache
工厂方法
// We choose a backend (for example 'File' or 'Sqlite'...) $backendName = ' [...] ' ; // 选择一个前端(例如'Core', 'Output', 'Page'...) $frontendName = ' [...] ' ; // 为选择的前端设置一个选项数组 $frontendOptions = array ([ ... ]); // 为选择的后端设置一个选项数组 $backendOptions = array ([ ... ]); // 创建实例(当然,最后两个参数是可选的) $cache = Zend_Cache :: factory( $frontendName , $backendName , $frontendOptions , $backendOptions );
(2)标记纪录
标记是给缓存纪录分类的一种方法。当你使用save()
方法保存一个缓存时,你可以给该缓存纪录设置一个或多个标记,多个标记以数组形式组织在一起,此后你不再需要该缓存纪录,使你可以清除所有指定标记的缓存纪录。
$cache -> save( $huge_data , ' myUniqueID ' , array ( ' tagA ' , ' tagB ' , ' tagC ' ));
$specificLifetime,如果该变量不为false,则将为该设定的cache设置一个特定的缓存有效期。
(3)缓存清理
删除特定id(标签)的Cache纪录,使用remove()
方法:
$cache -> remove( ' idToRemove ' );
在单个操作中删除多个Cache纪录,可以使用clean()
方法。例如,删除所有的缓存纪录:
// 清除所有缓存纪录 $cache -> clean(Zend_Cache :: CLEANING_MODE_ALL); // 仅清除过期的 $cache -> clean(Zend_Cache :: CLEANING_MODE_OLD);
如果你想删除标记为'tagA'和'tagC'的缓存项:
$cache -> clean(Zend_Cache :: CLEANING_MODE_MATCHING_TAG , array ( ' tagA ' , ' tagC ' ));
CLEANING_MODE_ALL
,CLEANING_MODE_OLD
, CLEANING_MODE_MATCHING_TAG
和CLEANING_MODE_NOT_MATCHING_TAG
. 后面的,正如它名称所暗示的,在清除操作中组合了一个标记数组,对其中的每个元素作处理。
三、Zend_Cache前端
1.1.Zend_Cache_Core
简介:Zend_Cache_Core
是一个特别的前端,因为他是模块的核心, 它是一个一般化(generic)的缓存前端,并且由其他类扩展。
所有的前端(output,function,class..)继承自Zend_Cache_Core
。因此它的方法和选项(描述如下)应该在其他的前端中可用,所以这里没有进行文档化,这些选项被传递给如前面例子中演示的工厂方法。
前端选项:
选项 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
caching | boolean | true | 打开 / 关闭缓存 (对被缓存脚本的调试非常有用) |
cache_id_prefix | string | null | 所有缓存 id 的前缀,如果设置为 null ,没有缓存 id 前缀使用。 缓存 id 前缀在缓存里创建一个命名空间,允许多个程序和网上共享缓存。 每个程序或网站可以使用不同的缓存 id 前缀,所以特定的缓存 id 可以使用多次。 |
lifetime | int | 3600 | 缓存生命期(秒), 如果设置为 null , 缓存永远有效. |
logging | boolean | false | 如果设置为true,日志纪录(通过使用Zend_Log )被激活(但是系统将变慢) |
write_control | boolean | true | 打开 / 关闭 写控制 (the cache is read just after writing to detect corrupt entries),打开写控制轻微地放慢缓存写的速度但不影响读(it can detect some corrupt cache files but it's not a perfect control) |
automatic_serialization | boolean | false | 打开 / 关闭自动序列化, 可以直接用于保存非字符串数据(但是很慢) |
automatic_cleaning_factor | int | 10 | 关闭 / 调整自动清理过程 (垃圾收集器): 0 表示不自动清理缓存,1 表示自动清理缓存,并且如果x > 1 表示x写操作后自动随机清理1次. |
ignore_user_abort | boolean | false | 如果设置为 true,核心将在 save() 方法里设置 ignore_user_abort PHP flag,以免在某些情况下缓存崩溃。 |
1.2.例子
// the complete construction (works in any case) if ( ! ( $cache -> test( $id ))) { // cache missed // [...] we make $data $cache -> save( $data ); } else { // cache hit $data = $cache -> load( $id ); } // we do something with $data
2.1 Zend_Cache_Frontend_Output
简介:Zend_Cache_Frontend_Output
是一个输出捕捉前端。它在PHP中使用输出缓冲捕获start()
和end()
方法间的一切输出。
2.2例子
// if it is a cache miss, output buffering is triggered if ( ! ( $cache -> start( ' mypage ' ))) { // output everything as usual echo ' Hello world! ' ; echo ' This is cached ( ' . time () . ' ) ' ; $cache -> end (); // output buffering ends } echo ' This is never cached ( ' . time () . ' ). ' ;
四、Zend_Cache后端
1.1、Zend_Cache_Backend_File:此后端把缓存纪录存储到文件中去(在一个选定的目录中)。
1.2、文件后端选项:
选项 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
cache_dir | string | '/tmp/' | 存放缓存文件的目录 |
file_locking | boolean | true | 启用/禁用文件锁定 : 在比较坏的情况下,能够避免缓存中断,但在多线程Web服务器或者NFS文件系统中没有任何帮助. |
read_control | boolean | true | 启用/禁用读控制: 如果启用,控制键被嵌入到缓存文件中,并且这个键将与读取后计算出的值进行比较. |
read_control_type | string | 'crc32' | 读控制类型 (仅在读控制启用时). 可用的值有: 'md5' (最好但最慢), 'crc32' (安全性稍差,但更快,更好的选择), 'adler32' (新选择,比 crc32 快), 'strlen' for a length only test (最快). |
hashed_directory_level | int | 0 | Hash目录结构层次: 0 表示"不使用hash的目录结构", 1 表示"一级目录结构" , 2表示"二级目录"... 次选项在你有成千上万的缓存文件是能够加速缓存.只有相关的基准测试才能帮助你选择合适的值.也许1或2是一个好的开始. |
hashed_directory_umask | int | 0700 | 目录结构的Unix 掩码 |
file_name_prefix | string | 'zend_cache' | 缓存文件前缀;小心使用此选项,因为当清除缓存时,在系统缓存目录(像 /tmp)中一个太generic的值将导致灾难. |
cache_file_umask | int | 0700 | 缓存文件掩码 |
metatadatas_array_max_size | int | 100 | metadatas 数组的内部最大尺寸(除非你知道你在做什么,不要更改这个值) |
2.1、Zend_Cache_Backend_Sqlite:此后端把缓存纪录存储到SQLite数据库中.
2.2、Sqlite 后端选项
选项 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
cache_db_complete_path (mandatory) | string | null | SQLite数据库的完整和路径(包括文件名) |
automatic_vacuum_factor | int | 10 | 禁用 / 调整自动清理过程. 自动清理过程将对数据库文件进行碎片整理(and make it smaller) 当clean() 或则 delete() 被调用时 : 0 表示不自动清理; 1 表示自动清理(当调用 delete() 或者 clean() 方法时) ; x (整数) > 1 => 当调用 delete() 或者 clean() 方法时随机清理1到x次. |
3.1、Zend_Cache_Backend_Memcached:本后端把缓存纪录存储到memcached服务器.memcached 是一个高性能的,分布式内存对象缓存系统.要使用此后端,你需要一个memecached守护进程(daemon)和memcache PECL 扩展.
3.2、Memcached后端选项
选项 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
servers | array | array(array('host' => 'localhost','port' => 11211, 'persistent' => true)) | 一个memcached服务器数组;其中每个memcached服务器描述为一个关联数组: 'host' => (string) : memcached服务器的名称, 'port' => (int) : memcached服务器端口, 'persistent' => (bool) : 是否使用到memcached服务器的持久连接 |
compression | boolean | false | 如果你想使用数据压缩,设置为true |