PHP之深入学习Yii2缓存Cache组件详细讲解

admin3年前PHP教程25
什么是缓存组件cache

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

定义缓存组件

yii2的缓存是通过组件component实现的,在项目的配置文件中,配置components->cache实现对缓存组件的定义。

项目配置文件的路径为config/web.php。

页面缓存pagecache

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

配置页面缓存

页面缓存的配置方式为,在控制器层controller中配置行为behaviors,通过调用过滤器filters的方式,在进入具体页面路径action的之前,对当前key进行计算,并判断缓存是否启用enabled缓存有效期duration。

基础配置代码如下所示


return [
    'pagecache' => [
        'class' => 'yii\filters\pagecache',
        'only' => ['index'],
        'variations' => [
            '/',
            yii::$app->request->isajax,
        ],
        'enabled'=>true,
        'duration' => yii::$app->params['pagecacheduration'],
    ],
];


过滤器是yii2中的一个概念,他可以在控制器初始化的时候加载并执行,我们可以用这个特点去做一些对控制器的数据的限制,比如控制缓存、用户权限控制。

这里我们将行为名称定义为pagecache,显然名字不重要,因为有的案例中,因为不同的页面缓存规则不一样,我会定义两个页面缓存的行为。

其中only为过滤器调用action的参数,用于限制哪些路径是启用action的。

页面缓存pagecache是缓存组件cache的一种应用

页面缓存的根本逻辑为

    配置缓存组件的实现比如文件缓存yii\caching\filecache页面缓存封装一层cache组件,再去调用存取逻辑

我们可以通过查看页面缓存源码vendor/yiisoft/yii2/filters/pagecache.php,我们可以在文件的第162行发现,这里调用的cache,就是对于缓存的实现。


$this->cache = instance::ensure($this->cache, 'yii\caching\cacheinterface');


自定义页面缓存过滤器

为什么我们需要自定义缓存组件呢,我归纳原因存在以下几种

缓存判断逻辑过于简单或复杂,不如自己重写痛快地多缓存key生成方式不满足业务需求

那么如何自定义呢?我个人推荐最简单粗暴的方式,继承。


use yii\filters\pagecache;
 
class pagecachectinfo extends pagecache
{
    这里是内部逻辑,不需要重写的方法可以不写。
    public $checkuser = true; //可以自定义变量
}


调用方式也是跟默认的页面缓存一样,只要换上对应的类即可。


'pagecacheinfo' => [
    'class' => 'common\components\pagecachectinfo',
    'only' => ['info'],
    'enabled'=>yii::$app->params['pagecacheenabled'],
    'variations' => [
        'ct/'.yii::$app->request->pathinfo,
        yii::$app->request->isajax
    ],
    'duration' => yii::$app->params['pagecacheinfo'],
    'checkuser' = false,
],


页面缓存key的计算

根据上一个步骤,我们可以重写计算key的方式,那么之前的key计算方式是什么样的呢?

文件位置vendor/yiisoft/yii2/filters/pagecache.php。


/**
 * @return array the key used to cache response properties.
 * @since 2.0.3
 */
protected function calculatecachekey()
{
    $key = [__class__];
    if ($this->varybyroute) {
        $key[] = yii::$app->requestedroute;
    }
    return array_merge($key, (array)$this->variations);
}


这里的缓存key是一个数组,数组内的元素依次是

当前类名varybyroute 一般为truevariations 验证,这个也是配置中获取的,根据上面的配置,则是页面路径和是否为ajax

如果是项目的首页,缓存的key则为


['yii\filters\pagecache','','/‘,0]


如果是个详情页面,key为


['yii\filters\pagecach', 'xxx/info','xxx/xxx/3xxxx74',0 ]


那么,这个key到底有什么用,为什么要单独拿出来说呢?

因为我们需要单独删除某个页面缓存。

主动清理过期缓存

根据源码vendor/yiisoft/yii2/caching/filecache.php


/**
 * stores a value identified by a key in cache.
 * this is the implementation of the method declared in the parent class.
 *
 * @param string $key the key identifying the value to be cached
 * @param string $value the value to be cached. other types (if you have disabled [[serializer]]) unable to get is
 * correct in [[getvalue()]].
 * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire.
 * @return bool true if the value is successfully stored into cache, false otherwise
 */
protected function setvalue($key, $value, $duration)
{
    $this->gc();
    $cachefile = $this->getcachefile($key);
    if ($this->directorylevel > 0) {
        @filehelper::createdirectory(dirname($cachefile), $this->dirmode, true);
    }
    // if ownership differs the touch call will fail, so we try to
    // rebuild the file from scratch by deleting it first
    // github/yiisoft/yii2/pull/16120
    if (is_file($cachefile) && function_exists('posix_geteuid') && fileowner($cachefile) !== posix_geteuid()) {
        @unlink($cachefile);
    }
    if (@file_put_contents($cachefile, $value, lock_ex) !== false) {
        if ($this->filemode !== null) {
            @chmod($cachefile, $this->filemode);
        }
        if ($duration <= 0) {
            $duration = 31536000; // 1 year
        }
 
        return @touch($cachefile, $duration + time());
    }
 
    $error = error_get_last();
    yii::warning("unable to write cache file '{$cachefile}': {$error['message']}", __method__);
    return false;
}


在设置缓存之前会主动调用清理缓存的方法gc()


/**
 * removes expired cache files.
 * @param bool $force whether to enforce the garbage collection regardless of [[gcprobability]].
 * defaults to false, meaning the actual deletion happens with the probability as specified by [[gcprobability]].
 * @param bool $expiredonly whether to removed expired cache files only.
 * if false, all cache files under [[cachepath]] will be removed.
 */
public function gc($force = false, $expiredonly = true)
{
    if ($force || mt_rand(0, 1000000) < $this->gcprobability) {
        $this->gcrecursive($this->cachepath, $expiredonly);
    }
}


这里问题就出现了,$gcprobability的默认值是10,也就是说,只有0.001%的概率会在设置缓存的同时清理过期缓存。

这不就跟没有一样!

所以对于缓存来说,需要我们主动定期清理过期缓存,不然对应的存储空间就会被占满。


yii::$app->cache->gc(true);


优化缓存配置

组件的cache在项目的配置文件中定义


'components' => ['cache' => [
    'class' => 'yii\caching\filecache',
],],


这里的自由度就出现了,现在这个配置,是文件缓存,也就是不管是数据缓存还是页面缓存,都是保存在文件里的

根据源码 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,redisyii\caching\wincache,使用 php wincache 扩展yii\caching\xcache,使用 php xcache扩展yii\caching\zenddatacache,使用zend data cache总结

我在本文中,通过渐进的方式,讲了如何使用yii2的缓存组件,对于一般的使用者来讲,已经涵盖了超过九成的坑。

如果你正在学习php,希望你收藏这篇文章,这会对你以后有所帮助。

到此这篇关于php之深入学习yii2缓存cache组件详细讲解的文章就介绍到这了,更多相关php之深入学习yii2缓存cache组件内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

免责声明:本文内容来自用户上传并发布,站点仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。请核实广告和内容真实性,谨慎使用。

相关文章

PHP如何实现HTTP验证

目录HTTP BasicHTTP Digest总结在日常开发中,我们进行用户登录的时候,大部分情况下都会使用 session 来保存用户登录信息,并以此为依据判断用户是否已登录。但其实 HTTP 也提...

PHP方法的返回值示例详解

前言不仅是PHP,大部分编程语言的函数或者叫方法,都可以用return来定义方法的返回值。从函数这个叫法来看,本身它就是一个计算操作,因此,计算总会有个结果,如果你在方法体中处理了结果,比如进行了持久...

台湾服务器ip地址怎么看

台湾服务器ip地址怎么看?要查看台湾服务器的IP地址,可以使用以下步骤:打开命令提示符或终端窗口。在Windows系统中,你可以按下Win+R键,在运行对话框中输入"cmd"并按下回车键打开命令提示符...

韩国站群服务器怎么优化访问速度?韩国多ip服务器的原理是什么?

韩国站群服务器怎么优化访问速度?1、提升韩国站群服务器的idc信息中心环境,包括周围的温度、湿度和通透性等;2、提升韩国站群服务器的配置,包括韩国站群服务器的处理器、内存和硬盘大小等;3、提升网站程序...

购买宁波高防服务器进行ddos攻击防御多少g才够用

购买宁波高防服务器进行ddos攻击防御多少g才够用?购买宁波高防服务器进行DDoS攻击防御时,需要考虑多个因素,包括攻击类型、攻击流量、服务器的带宽和防护能力等等。因此,不同的防御需求需要不同的防御能...

浅谈swoole的作用与原理

目录PHP 中的 Node ?Swoole 到底是什么?如何让它运行?使用 Docker 运行 SwooleSwoole 可以做什么?基于 Swoole 实现 HTTP 服务HTTP Server 标...