• 售前

  • 售后

热门帖子
入门百科

PHP之深入学习Yii2缓存Cache组件具体解说

[复制链接]
银鲜目江探 显示全部楼层 发表于 2021-8-14 14:35:05 |阅读模式 打印 上一主题 下一主题
什么是缓存组件Cache

缓存是提升 Web 应用性能轻便有效的方式。 通过将相对静态的数据存储到缓存并在收到请求时取回缓存, 应用程序便节省了每次重新天生这些数据所需的时间。

界说缓存组件

Yii2的缓存是通过组件Component实现的,在项目的配置文件中,配置components->cache实现对缓存组件的界说。
项目配置文件的路径为config/web.php。

页面缓存PageCache

作为网站来讲,Yii2的页面缓存非常便捷地将已经渲染完全的网页结果生存起来,并在一个缓存周期内不需要再次处置惩罚页面内部的控制器动作逻辑。
配置页面缓存

页面缓存的配置方式为,在控制器层Controller中配置行为behaviors,通过调用过滤器filters的方式,在进入具体页面路径action的之前,对当前key进行计算,并判定缓存是否启用enabled缓存有效期duration。
底子配置代码如下所示
  1.         return [
  2.             'pageCache' => [
  3.                 'class' => 'yii\filters\PageCache',
  4.                 'only' => ['index'],
  5.                 'variations' => [
  6.                     '/',
  7.                     Yii::$app->request->isAjax,
  8.                 ],
  9.                 'enabled'=>true,
  10.                 'duration' => Yii::$app->params['pageCacheDuration'],
  11.             ],
  12.         ];
复制代码
过滤器是Yii2中的一个概念,他可以在控制器初始化的时间加载并实行,我们可以用这个特点去做一些对控制器的数据的限定,比如控制缓存、用户权限控制。
这里我们将行为名称界说为pageCache,显然名字不紧张,因为有的案例中,因为差异的页面缓存规则不一样,我会界说两个页面缓存的行为。
此中only为过滤器调用action的参数,用于限定哪些路径是启用action的。
页面缓存PageCache是缓存组件Cache的一种应用

页面缓存的根本逻辑为
       
  • 配置缓存组件的实现比如文件缓存yii\caching\FileCache   
  • 页面缓存封装一层Cache组件,再去调用存取逻辑
我们可以通过检察页面缓存源码vendor/yiisoft/yii2/filters/PageCache.php,我们可以在文件的第162行发现,这里调用的cache,就是对于缓存的实现。
  1. $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface');
复制代码
自界说页面缓存过滤器

为什么我们需要自界说缓存组件呢,我归纳原因存在以下几种
       
  • 缓存判定逻辑过于简单或复杂,不如本身重写痛快地多   
  • 缓存key天生方式不满意业务需求
那么怎样自界说呢?我个人保举最简单粗暴的方式,继续。
  1. use yii\filters\PageCache;
  2. class PageCacheCtInfo extends PageCache
  3. {
  4.         这里是内部逻辑,不需要重写的方法可以不写。
  5.         public $checkUser = true; //可以自定义变量
  6. }
复制代码
调用方式也是跟默认的页面缓存一样,只要换上对应的类即可。
  1.             'pageCacheInfo' => [
  2.                 'class' => 'common\components\PageCacheCtInfo',
  3.                 'only' => ['info'],
  4.                 'enabled'=>Yii::$app->params['pageCacheEnabled'],
  5.                 'variations' => [
  6.                     'ct/'.Yii::$app->request->pathInfo,
  7.                     Yii::$app->request->isAjax
  8.                 ],
  9.                 'duration' => Yii::$app->params['pageCacheInfo'],
  10.                 'checkUser' = false,
  11.             ],
复制代码
页面缓存key的计算

根据上一个步调,我们可以重写计算key的方式,那么之前的key计算方式是什么样的呢?
文件位置vendor/yiisoft/yii2/filters/PageCache.php。
  1.     /**
  2.      * @return array the key used to cache response properties.
  3.      * @since 2.0.3
  4.      */
  5.     protected function calculateCacheKey()
  6.     {
  7.         $key = [__CLASS__];
  8.         if ($this->varyByRoute) {
  9.             $key[] = Yii::$app->requestedRoute;
  10.         }
  11.         return array_merge($key, (array)$this->variations);
  12.     }
复制代码
这里的缓存key是一个数组,数组内的元素依次是
       
  • 当前类名   
  • varyByRoute 一样平常为true   
  • variations 验证,这个也是配置中获取的,根据上面的配置,则是页面路径和是否为ajax
如果是项目的首页,缓存的key则为
  1. ['yii\filters\PageCache','','/‘,0]
复制代码
如果是个详情页面,key为
  1. ['yii\filters\PageCach', 'xxx/info','xxx/xxx/3xxxx74.html',0 ]
复制代码
那么,这个key到底有什么用,为什么要单独拿出来说呢?
因为我们需要单独删除某个页面缓存。
自动清算过期缓存

根据源码vendor/yiisoft/yii2/caching/FileCache.php
  1.     /**
  2.      * Stores a value identified by a key in cache.
  3.      * This is the implementation of the method declared in the parent class.
  4.      *
  5.      * @param string $key the key identifying the value to be cached
  6.      * @param string $value the value to be cached. Other types (If you have disabled [[serializer]]) unable to get is
  7.      * correct in [[getValue()]].
  8.      * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
  9.      * @return bool true if the value is successfully stored into cache, false otherwise
  10.      */
  11.     protected function setValue($key, $value, $duration)
  12.     {
  13.         $this->gc();
  14.         $cacheFile = $this->getCacheFile($key);
  15.         if ($this->directoryLevel > 0) {
  16.             @FileHelper::createDirectory(dirname($cacheFile), $this->dirMode, true);
  17.         }
  18.         // If ownership differs the touch call will fail, so we try to
  19.         // rebuild the file from scratch by deleting it first
  20.         // https://github.com/yiisoft/yii2/pull/16120
  21.         if (is_file($cacheFile) && function_exists('posix_geteuid') && fileowner($cacheFile) !== posix_geteuid()) {
  22.             @unlink($cacheFile);
  23.         }
  24.         if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) {
  25.             if ($this->fileMode !== null) {
  26.                 @chmod($cacheFile, $this->fileMode);
  27.             }
  28.             if ($duration <= 0) {
  29.                 $duration = 31536000; // 1 year
  30.             }
  31.             return @touch($cacheFile, $duration + time());
  32.         }
  33.         $error = error_get_last();
  34.         Yii::warning("Unable to write cache file '{$cacheFile}': {$error['message']}", __METHOD__);
  35.         return false;
  36.     }
复制代码
在设置缓存之前会自动调用清算缓存的方法gc()
  1.     /**
  2.      * Removes expired cache files.
  3.      * @param bool $force whether to enforce the garbage collection regardless of [[gcProbability]].
  4.      * Defaults to false, meaning the actual deletion happens with the probability as specified by [[gcProbability]].
  5.      * @param bool $expiredOnly whether to removed expired cache files only.
  6.      * If false, all cache files under [[cachePath]] will be removed.
  7.      */
  8.     public function gc($force = false, $expiredOnly = true)
  9.     {
  10.         if ($force || mt_rand(0, 1000000) < $this->gcProbability) {
  11.             $this->gcRecursive($this->cachePath, $expiredOnly);
  12.         }
  13.     }
复制代码
这里题目就出现了,$gcProbability的默认值是10,也就是说,只有0.001%的概率会在设置缓存的同时清算过期缓存。
这不就跟没有一样!
以是对于缓存来说,需要我们自动定期清算过期缓存,否则对应的存储空间就会被占满。
  1. Yii::$app->cache->gc(true);
复制代码
优化缓存配置

组件的cache在项目的配置文件中界说
  1. 'components' => ['cache' => [
  2.     'class' => 'yii\caching\FileCache',
  3. ],],
复制代码
这里的自由度就出现了,如今这个配置,是文件缓存,也就是不管是数据缓存还是页面缓存,都是生存在文件里的
根据源码 public $cachePath = '@runtime/cache';
缓存的文件是放在runtime/cache文件夹的
那么题目就出现了,磁盘的性能是有瓶颈的,文件读写会影响缓存性能。
目前可选的缓存有
       
  • yii\caching\ApcCache,APC扩展   
  • yii\caching\DbCache,数据库缓存   
  • yii\caching\DummyCache,假的缓存,就是如今没条件上缓存先把坑占上   
  • yii\caching\FileCache,文件缓存   
  • yii\caching\MemCache,使用 PHP memcache 和 memcached 扩展   
  • yii\redis\Cache,redis   
  • yii\caching\WinCache,使用 PHP WinCache 扩展   
  • yii\caching\XCache,使用 PHP XCache扩展   
  • yii\caching\ZendDataCache,使用Zend Data Cache
总结

我在本文中,通过渐进的方式,讲了怎样使用Yii2的缓存组件,对于一样平常的使用者来讲,已经涵盖了超过九成的坑。
如果你正在学习PHP,希望你收藏这篇文章,这会对你以后有所资助。

到此这篇关于PHP之深入学习Yii2缓存Cache组件详细讲解的文章就介绍到这了,更多相关PHP之深入学习Yii2缓存Cache组件内容请搜刮草根技能分享从前的文章或继续欣赏下面的相关文章希望各人以后多多支持草根技能分享!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作