【PHP】Yii2的Cache组件cachePath遇到的坑,亲测可用

举报
小雨青年 发表于 2022/03/28 22:13:09 2022/03/28
【摘要】 💪 日拱一卒无有尽,功不唐捐终入海 👀 关注收藏不迷路,早晚都能成大神 业务需求 由于业务需要,用户登录之后,我需要判断用户是否为违禁用户组,如果是,就要主动退出登录。 基本流程为 ...

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

业务需求

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

基本流程为

  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);
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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;
    }



  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Bug描述

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

分析原因

先抛出根本原因:

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

详细代码

checkUserRight阶段,设置了cachePath


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

  
 
  • 1
  • 2
  • 3

由于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);
    }


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

得到的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;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

文章来源: coderfix.blog.csdn.net,作者:小雨青年,版权归原作者所有,如需转载,请联系作者。

原文链接:coderfix.blog.csdn.net/article/details/118197398

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。