PHPYii2的Cache组件cachePath遇到的坑,亲测可用

Posted 雨果虾滑猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHPYii2的Cache组件cachePath遇到的坑,亲测可用相关的知识,希望对你有一定的参考价值。

💪 日拱一卒无有尽,功不唐捐终入海
👀 关注收藏不迷路,早晚都能成大神

业务需求

由于业务需要,用户登录之后,我需要判断用户是否为违禁用户组,如果是,就要主动退出登录。

基本流程为

  1. 进入页面
  2. 判断用户组
  3. 退出登录

实现细节

实现具体在判断用户组,由于项目涉及到的Action众多,我就把处理用户组的调用放在了Controller里。

代码为

class SiteController extends Controller
{
    public function beforeAction($action)
    {
            $loginuid = Yii::$app->user->getId();
            if($loginuid && XXXX::checkUserRight($loginuid, coderfix.blog.csdn.net::INTER_FORCE_LOGOUT)){
            Yii::$app->user->logout();
        }
        return parent::beforeAction($action);
    }

}

checkUserRight代码为

    /**
     * 判断用户是否拥有对应的权限
     * @param $uid
     * @param $action
     * @return bool | array
     */
    public static function checkUserRight($uid,$action = null){
        $cache = Yii::$app->cache;
        $key = 'coderfix.blog.csdn.net'.$uid;
        $alias = '@coderfix.blog.csdn.net/runtime/cache';
        $cache->cachePath = \\Yii::getAlias($alias);
        $rights = $cache->getOrSet($key, function ()use ($uid) {
			//具体业务查询用户组以及对应权限
        },Yii::$app->params['CacheDuration']);
        $cache->cachePath = $cachePath;
        if($action && isset($rights[$action])){
            return $rights[$action];
        }
        return $rights;
    }


Bug描述

这个项目有多个内部app组成,一个主页生成的缓存之后,另一个主页直接获取对应的缓存,并没有调用业务逻辑,生成自己页面的缓存。

分析原因

先抛出根本原因:

由于页面执行的页面缓存pageCache使用了其他app的首页缓存,他们的缓存路径被设置成了同一个,并且因为都是主页,所以缓存计算的key是一致的,导致加载缓存位置一致。

详细代码

checkUserRight阶段,设置了cachePath


$cache = Yii::$app->cache; 
$cache->cachePath = \\Yii::getAlias($alias); //这里

由于Yii2的实例是单例模式,一次运行中的Yii对象一直维持一个,所以我在检测权限步骤拿缓存的时候,设置的缓存路径一直生效。

而且ControllerbeforeAction的方法在整个生命周期的前面

就导致了后面页面缓存pageCache调用的Cache组件的缓存路径被固定

根据Yii2项目源码vendor/yiisoft/yii2/filters/PageCache.php中计算key的方法

    /**
     * @return array the key used to cache response properties.
     * @since 2.0.3 coderfix.blog.csdn.net
     */
    protected function calculateCacheKey()
    {
        $key = [__CLASS__];
        if ($this->varyByRoute) {
            $key[] = Yii::$app->requestedRoute;
        }
        return array_merge($key, (array)$this->variations);
    }

得到的key就是一致的。

解决方案

临时使用缓存组件,设置cachePath之后,使用完成之后,再把之前值改回去。

		$cache = Yii::$app->cache;
        $cachePath = $cache->cachePath;
        $key = 'coderfix.blog.csdn.net'.$uid;
        $alias = '@coderfix.blog.csdn.net/runtime/cache';
        $cache->cachePath = \\Yii::getAlias($alias);
        //这里执行缓存操作逻辑
        $cache->cachePath = $cachePath;

🏃‍♂️ 好记性不如烂笔头,收藏本文吧!技术求知路好走💼!

以上是关于PHPYii2的Cache组件cachePath遇到的坑,亲测可用的主要内容,如果未能解决你的问题,请参考以下文章

yii2.0 删除文件夹

yii2_文件缓存

PHPYii2使用ActiveDataProvider超出页码一直展示最后一页的解决方案源码分析亲测有效

PHPYii2中事务的使用以及代码实例

swift清理缓存

CEF浏览器代码收集