内容简介:ThinkPhp缓存原理及使用详解
做这个项目时,服务端最开始是使用原生 PHP 写的,在查询数据库时,没有做任何缓存,后来做到商城,采用thinkPHP框架,页面加载突然提速了很多,专门和做PHP的朋友交流了一下,了解到thinkPHP内置缓存机制,无需从磁盘实时查询Mysql,大多数时候从缓存(内存)中读取数据。记录如下:
原理
如果没有缓存的网站是百万级或者千万级的访问量,会给数据库或者服务器造成很大的压力,通过缓存,大幅减少服务器和数据库的负荷,假如我们把读取数据的过程分为三个层,第一个是访问层,第一个是缓存层,第三个是数据库存取层,如果没有缓存层,访问层是直接从数据库存取层读取数据,而设置缓存后,访问层不再是直接在数据库存取层读取,而是从缓存层读取数据.
我们做个简单的对比,假设一个页面,在一个小时可被访问100万次,如果这个页面每次被访问的时候,都直接读取数据库后再编译生成,在一个小时内将会重复性的生成100万次,而如果这个页面被周期性的缓存10分钟,也就是每间隔10分钟缓存数据才会被生成一次,一个小时内只会被生成6次,两种方式一对比,效果明显,两种比较下服务器负荷的压力比差别十几万倍以上,缓存技术将使得网站负载在高峰期游刃有余.
缓存使用
ThinkPHP提供了方便的缓存方式,包括数据缓存、静态缓存和查询缓存等,支持包括文件方式、APC、Db、Memcache、Shmop、 Sqlite 、 Redis 、Eaccelerator和Xcache在内的动态数据缓存类型,以及可定制的静态缓存规则,并提供了快捷方法进行存取操作。
数据缓存
ThinkPHP缓存文件的配置
Home是我建立的前台项目,在Home/Conf/config.PHP找到缓存的配置文件,配置如下:
<?php return array( 'DB_TYPE'=>'mysql', 'DB_HOST'=>'127.0.0.1', 'DB_NAME'=>'w3note', 'DB_USER'=>'root', 'DB_PWD'=>'123456', 'DB_PORT'=>'3306', 'DB_PREFIX'=>'w3_', 'DATA_CACHE_TYPE'=>'file',//设置缓存方式为file 'DATA_CACHE_TIME'=>'600',//缓存周期600秒 ); ?>
ThinkPHP缓存函数的使用
在thinkPHP中,使用快捷缓存函数S()进行缓存,其用法如下:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
实例演示
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
访问http://127.0.0.1/Home/index.PHP/Index/index,
第一次访问:
这是直接读取数据库的数据 array(10) { [0] => array(12) { ["id"] => string(1) "1" ["catid"] => string(2) "13" ["title"] => string(4) "thinkphp的缓存技术" ["content"] => string(8) "thinkphp的缓存技术" ["tags"] => string(4) "缓存" ["thumb"] => string(0) "" ["description"] => string(7) "thinkphp的缓存技术" ["inputtime"] => string(10) "1348370202" ["posid"] => string(1) "1" ["ord"] => string(1) "2" ["hits"] => string(1) "1" ["status"] => string(1) "1" }
第二次访问:
array(10) { [0] => array(12) { ["id"] => string(1) "1" ["catid"] => string(2) "13" ["title"] => string(4) "thinkphp的缓存技术" ["content"] => string(8) "thinkphp的缓存技术" ["tags"] => string(4) "缓存" ["thumb"] => string(0) "" ["description"] => string(7) "thinkphp的缓存技术" ["inputtime"] => string(10) "1348370202" ["posid"] => string(1) "1" ["ord"] => string(1) "2" ["hits"] => string(1) "1" ["status"] => string(1) "1" }
说明:第一次运行时,会打印出如上面所示信息,刷新一下页面后,少了 “ 这是直接读取数据库的数据" ,说明读取的是先前生成的缓存数据.
快速缓存
如果你仅仅是希望用文件的方式缓存一些简单的数据,并且没有有效期的概念,那么系统还提供了一个快速缓存方法F可以用来更快的操作。
快速缓存Data数据,默认保存在DATA_PATH目录下面
F('data',$Data);
快速缓存Data数据,保存到指定的目录
F('data',$Data,TEMP_PATH);
获取缓存数据
$Data = F('data');
删除缓存数据
F('data',NULL);
F方法支持自动创建缓存子目录,在DATA_PATH目录下面缓存data数据,如果User子目录不存在,则自动创建:
F('User/data',$Data);
3.1.2版本开始F方法支持使用通配符批量删除功能,使用如下:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
0
表示删除DATA_PATH.'User/'目录下面的数据缓存。
系统内置的数据字段信息缓存就是用了快速缓存机制。
查询缓存
对于及时性要求不高的数据查询,我们可以使用查询缓存功能来提高性能,而且无需自己使用缓存方法进行缓存和获取。
APP/config.PHP配置:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
1
查询缓存功能支持所有的数据库,并且支持所有的缓存方式和有效期。
在使用查询缓存的时候,只需要调用Model类的cache方法,例如:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
2
如果使用了cache(true) ,则在查询的同时会根据当前的查询 SQL 生成查询缓存,默认情况下缓存方式采用DATA_CACHE_TYPE参数设置的缓存方式(系统默认值为File表示采用文件方式缓存),缓存有效期是DATA_CACHE_TIME 参数设置的时间,也可以单独制定查询缓存的缓存方式和有效期:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
3
表示当前查询缓存的缓存方式为xcache,并且缓存有效期为60秒。
同样的查询,如果没有使用cache方法,则不会获取或者生成任何缓存,即便是之前调用过Cache方法。
查询缓存只是供内部调用,如果希望查询缓存开放给其他程序调用,可以指定查询缓存的Key,例如:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
4
则可以在外部通过S方法直接获取查询缓存的内容,
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
5
除了select方法之外,查询缓存还支持find和getField方法,以及他们的衍生方法(包括统计查询和动态查询方法)。具体应用的时候可以根据需要选择缓存方式和缓存有效期。
SQL解析缓存
除了查询缓存之外,ThinkPHP还支持SQL解析缓存,因为ThinkPHP的ORM机制,所有的SQL都是动态生成的,然后由数据库驱动执行。
所以如果你的应用有大量的SQL查询需求,那么可以开启SQL解析缓存以减少SQL解析提高性能。要开启SQL解析缓存,只需要设置:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
6
即可开启数据库查询的SQL创建缓存,默认缓存方式为文件方式,还可以支持xcache和apc方式缓存,只需要设置:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
7
我们知道,一个项目的查询SQL的量可能会非常巨大,所以有必要设置下缓存的队列长度,例如,我们希望SQL解析缓存不超过20条记录,可以设置:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
8
注意:只有查询方法才支持SQL解析缓存
静态缓存
要使用静态缓存功能,需要开启HTML_CACHE_ON参数,并且使用HTML_CACHE_RULES配置参数设置静态缓存规则文件 。
虽然也可以在应用配置文件中定义静态缓存规则,但是建议是在模块配置文件中为不同的模块定义静态缓存规则。
静态规则定义
静态规则的定义方式如下:
S('data',$Data);//使用data标识缓存$Data数据 S('data',$Data,600);// 缓存$Data数据600秒 $Data = S('data');// 获取缓存数据 S('data',NULL);// 删除缓存数据
9
定义格式1采用数组方式 便于单独为某个静态规则设置不同的有效期,定义格式2采用字符串方式订阅静态规则,同时采用HTML_CACHE_TIME设置的全局静态缓存有效期。
静态缓存文件的根目录在HTML_PATH定义的路径下面,并且只有定义了静态规则的操作才会进行静态缓存。 并且静态缓存支持不同的存储类型。 静态缓存仅在GET请求下面有效。
静态地址
静态地址包括下面几种定义格式:
第一种是定义全局的操作静态规则,例如定义所有的read操作的静态规则为:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
0
其中,{id}
表示取$_GET['id']
为静态缓存文件名,第二个参数表示缓存60秒。
第二种是定义全局的控制器静态规则,例如定义所有的User控制器的静态规则为:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
1
其中,{:action}
表示当前的操作名称
第三种是定义某个控制器的操作的静态规则,例如,我们需要定义Blog控制器的read操作进行静态缓存
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
2
第四种方式是定义全局的静态缓存规则,这个属于特殊情况下的使用,任何模块的操作都适用,例如
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
3
表示根据当前的URL进行缓存。
静态规则
静态规则是用于定义要生成的静态文件的名称,静态规则的定义要确保不会冲突,写法可以包括以下情况:
使用系统变量
包括 _GET、_REQUEST、_SERVER、_SESSION、_COOKIE
格式:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
4
例如:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
5
使用框架特定的变量
{:module} 、{:controller} 和{:action}
分别表示当前模块名、控制器名和操作名。
例如:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
6
使用_GET变量
{var|function}也就是说 {id}其实等效于 {$_GET.id}
直接使用函数
{|function} 例如:{|time}
支持混合定义
例如我们可以定义一个静态规则为:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
7
在{}之外的字符作为字符串对待,如果包含有"/",会自动创建目录。
例如,定义下面的静态规则:
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
8
则会在静态目录下面创建模块名称的子目录,然后写入操作名_id.sHTML 文件。
静态缓存有效期
单位为秒。如果不定义,则会获取配置参数HTML_CACHE_TIME的设置值,如果定义为0则表示永久缓存。
附加规则
通常用于对静态规则进行函数运算,例如
<?php // 本类由系统自动生成,仅供测试用途 class IndexAction extends Action{ public function index(){ //如果有缓存,则读取缓存数据 //如果没有缓存,则读取数据库当中的数据放入缓存 $lists=S('lists'); if(emptyempty($lists)){ $news=M('news'); $lists=$news->select(); S('lists',$lists,600); echo '这是直接读取数据库的数据'; } dump($list); ?>
9
翻译后的静态规则是
这是直接读取数据库的数据 array(10) { [0] => array(12) { ["id"] => string(1) "1" ["catid"] => string(2) "13" ["title"] => string(4) "thinkphp的缓存技术" ["content"] => string(8) "thinkphp的缓存技术" ["tags"] => string(4) "缓存" ["thumb"] => string(0) "" ["description"] => string(7) "thinkphp的缓存技术" ["inputtime"] => string(10) "1348370202" ["posid"] => string(1) "1" ["ord"] => string(1) "2" ["hits"] => string(1) "1" ["status"] => string(1) "1" }
0
以上所述就是小编给大家介绍的《ThinkPhp缓存原理及使用详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Book of CSS3
Peter Gasston / No Starch Press / 2011-5-13 / USD 34.95
CSS3 is the technology behind most of the eye-catching visuals on the Web today, but the official documentation can be dry and hard to follow. Luckily, The Book of CSS3 distills the heady technical la......一起来看看 《The Book of CSS3》 这本书的介绍吧!