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 其它

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

相关文章
|
5天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2486 17
|
6天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1085 3
|
云安全 安全 网络安全
|
5天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
|
6天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
18天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3240 51

热门文章

最新文章