ThinkPhp缓存原理及使用详解

栏目: PHP · 发布时间: 6年前

内容简介:ThinkPhp缓存原理及使用详解

做这个项目时,服务端最开始是使用原生 PHP 写的,在查询数据库时,没有做任何缓存,后来做到商城,采用thinkPHP框架,页面加载突然提速了很多,专门和做PHP的朋友交流了一下,了解到thinkPHP内置缓存机制,无需从磁盘实时查询Mysql,大多数时候从缓存(内存)中读取数据。记录如下:

原理

如果没有缓存的网站是百万级或者千万级的访问量,会给数据库或者服务器造成很大的压力,通过缓存,大幅减少服务器和数据库的负荷,假如我们把读取数据的过程分为三个层,第一个是访问层,第一个是缓存层,第三个是数据库存取层,如果没有缓存层,访问层是直接从数据库存取层读取数据,而设置缓存后,访问层不再是直接在数据库存取层读取,而是从缓存层读取数据.

我们做个简单的对比,假设一个页面,在一个小时可被访问100万次,如果这个页面每次被访问的时候,都直接读取数据库后再编译生成,在一个小时内将会重复性的生成100万次,而如果这个页面被周期性的缓存10分钟,也就是每间隔10分钟缓存数据才会被生成一次,一个小时内只会被生成6次,两种方式一对比,效果明显,两种比较下服务器负荷的压力比差别十几万倍以上,缓存技术将使得网站负载在高峰期游刃有余.

缓存使用

ThinkPHP提供了方便的缓存方式,包括数据缓存、静态缓存和查询缓存等,支持包括文件方式、APC、Db、Memcache、Shmop、 SqliteRedis 、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缓存原理及使用详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法霸权

算法霸权

[美] 凯西·奥尼尔 / 马青玲 / 中信出版集团 / 2018-9-1 / 69.00元

数据科学家凯西•奥尼尔认为,我们应该警惕不断渗透和深入我们生活的数学模型——它们的存在,很有可能威胁到我们的社会结构。 我们生活在一个依赖“算法”的时代,它对我们生活的影响越来越大,我们去哪里上学,我是不是应该贷款买车,我们应该花多少钱来买健康保险,这些都不是由人来决定的,而是由大数据模型来决定的。从理论上来说,这一模型应该让社会更加公平,每一个人的衡量标准都是一样的,偏见是不存在的。 ......一起来看看 《算法霸权》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

SHA 加密
SHA 加密

SHA 加密工具