Yii2 理解filters

简介: 版本ActionFilterAccessControlAccessRuleVerbFilter其它1 版本// yii\BaseYii\getVersionpublic static function getVersion(){ return '2.0.10';}2 ActionFilter动作过滤器的基

1 版本

// yii\BaseYii\getVersion
public static function getVersion()
{
    return '2.0.10';
}

2 ActionFilter

动作过滤器的基类, 有两个重要的变量, 这两个变量都是存储action id

$except: 过滤器将不会应用于在这里面出现的action,即使出现在$only中,过滤器也不会有效。
$only: 如果为空, 该过滤器会应用于其owner下的所有过滤器。如果不为空, 则只应用于在这里面出现的action。

以上规则见代码:

protected function isActive($action)
{
    $id = $this->getActionId($action);
    // 如果为空, 过滤器判断为有效
    if (empty($this->only)) 
    {
        $onlyMatch = true;
    } 
    else 
    {
        // 判断action是否出现在$only中
        $onlyMatch = false;
        foreach ($this->only as $pattern) 
        {
            if (fnmatch($pattern, $id)) 
            {
                $onlyMatch = true;
                break;
            }
        }
    }
    // --------- 拦路虎: 在这里面出现,即使前面判断过滤器有效, 也会变为无效
    $exceptMatch = false;
    foreach ($this->except as $pattern) 
    {
        if (fnmatch($pattern, $id)) 
        {
            $exceptMatch = true;
            break;
        }
    }

    return !$exceptMatch && $onlyMatch;
}

3 AccessControl

该过滤器提供简单的访问控制

$user: 将会指向User,用于判断玩家的情况, 比如 $user->getIsGuest()判断玩家是否是游客。
$denyCallback: 如果没有通过过滤器, 将会指向denyCallback指向的回调函数, 如果没有设置,就会读取默认的denyAccess
protected function denyAccess($user)
{
    // 如果是游客, 则跳珠到登陆界面
    if ($user->getIsGuest()) 
    {
        // 如果没有定义登陆界面,则会报异常
        $user->loginRequired();
    } 
    else 
    {
        throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
    }
}
$ruleConfig: 默认的规则,指向yii\filters\AccessRule, 这个规则在后文讲述
$rules: 自定义的规则, 将会和$ruleConfig进行合并, 如果有相同项,会覆盖$ruleConfig
// 基类Object的构造函数中调用
public function init()
{
    parent::init();
    $this->user = Instance::ensure($this->user, User::className());
    foreach ($this->rules as $i => $rule) 
    {
        if (is_array($rule)) 
        {
            // 如果没有更改$ruleConfig变量, 这里将rule配置一一生成AccessRule对象
            $this->rules[$i] = Yii::createObject(array_merge($this->ruleConfig, $rule));
        }
    }
}

客户端在请求的时候,会创建$controller, $action,然后执行$controller->runAction($action, …), 在runAction中,将会先执行过滤器的beforeAction,在这里也就是yii\filters\AccessController::beforeAction

具体流程见Yii2 分析Controller::behaviors 触发过程
http://blog.csdn.net/alex_my/article/details/54172619

public function beforeAction($action)
{
    $user = $this->user;
    $request = Yii::$app->getRequest();

    foreach ($this->rules as $rule) 
    {
        // --------------- $rule->allows将在下文分析
        if ($allow = $rule->allows($action, $user, $request)) 
        {
            return true;
        } 
        // --------------- 如果有定义denyCallback,则调用
        // --------------- 否则调用默认的denyAccess
        elseif ($allow === false) 
        {
            if (isset($rule->denyCallback)) 
            {
                call_user_func($rule->denyCallback, $rule, $action);
            } 
            elseif ($this->denyCallback !== null)
            {
                call_user_func($this->denyCallback, $rule, $action);
            } 
            else 
            {
                $this->denyAccess($user);
            }
            return false;
        }
    }
    if ($this->denyCallback !== null) 
    {
        call_user_func($this->denyCallback, null, $action);
    } 
    else 
    {
        $this->denyAccess($user);
    }
    return false;
}

4 AccessRule

该类是AccessController的规则对象,其成员变量和AccessController中的rules合并,且相同键名的会被后者覆盖

$allow: 如果为true, 如果规则验证通过, 则表示该规则通过验证。如果为false,表示该规则一定不能通过。
$actions: 表示该规则应用于哪些action中, 如果为空, 则表示应用于所有的action中
$controllers: 表示该规则应用于哪些controller中,假设有BaseController::Controller做为自定义的控制器基类,在BaseController::behaviors可以设置规则只用于哪些派生类中:
public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['login', 'error', 'register', 'offline'],
                    'allow' => true,
                    'controllers' => [
                        'site'
                    ]
                ]
            ]
        ]
    ];
$roles: 指定该规则应用于哪些角色, 比如在rules中添加roles => ['Wang']
有两个特殊的角色:
?: 表示未登陆的游客
@: 表示已登陆的角色
$ips: 验证ip
$verbs: 指定该规则应用于哪些请求方法,比如GET, POST
$matchCallback: 通过调用自定义的函数来判断规则是否通过
$denyCallback: 表示验证未通过将会调用的函数

验证过程:

public function allows($action, $user, $request)
{
    if ($this->matchAction($action)
        && $this->matchRole($user)
        && $this->matchIP($request->getUserIP())
        && $this->matchVerb($request->getMethod())
        && $this->matchController($action->controller)
        && $this->matchCustom($action)
    ) 
    {
        return $this->allow ? true : false;
    } 
    else 
    {
        return null;
    }
}

5 VerbFilter

用于验证http请求的方法

public function behaviors()
{
    return [
        [
            'class' => VerbFilter::className(),
            // ---------- 指定action的访问规则
            'actions' => [
                'create' => ['get', 'post'],
                'delete' => ['post'],
                'upload'=>['post'],
                // 其它的都是用get
                '*' => ['get']
            ]
        ]
    ];
}

该过滤器将会执行EVENT_BEFORE_ACTION,在动作执行前进行判断, 验证未通过,则action不会继续执行下去。

6 其它

其余暂未使用到, 有用到再添加

相关文章
|
6天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1917 6
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
5天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
651 111
|
14天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2551 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
15天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1419 2
|
13天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1528 2
|
16天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1477 55