【PHP】Yii2的Cache组件cachePath遇到的坑,亲测可用
💪 日拱一卒无有尽,功不唐捐终入海
👀 关注收藏不迷路,早晚都能成大神
业务需求
由于业务需要,用户登录之后,我需要判断用户是否为违禁用户组,如果是,就要主动退出登录。
基本流程为
- 进入页面
- 判断用户组
- 退出登录
实现细节
实现具体在判断用户组,由于项目涉及到的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对象一直维持一个,所以我在检测权限步骤拿缓存的时候,设置的缓存路径一直生效。
而且Controller
中beforeAction
的方法在整个生命周期的前面
就导致了后面页面缓存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
- 点赞
- 收藏
- 关注作者
评论(0)