Yii2 分析Controller::behaviors 触发过程

简介: 版本示例客户端请求后的运行流程简述1 版本// yii\BaseYii\getVersionpublic static function getVersion(){ return '2.0.10';}2 示例AccessControl是框架自带的,位于yii\filters目录下class SiteC

1 版本

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

2 示例

AccessControl是框架自带的,位于yii\filters目录下

class SiteController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['login', 'error', 'register', 'offline'],
                        'allow' => true,
                    ],
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ]
                ]
            ]
        ];
    }
}

3 客户端请求后的运行流程

具体运行流程请参考Yii2分析运行流程
http://blog.csdn.net/alex_my/article/details/54142711

最终会在yii\base\Module::runAction中
创建controller, action
然后执行$controller->runAction

public function runAction($route, $params = [])
{
    $parts = $this->createController($route);
    if (is_array($parts)) 
    {
        list($controller, $actionID) = $parts;
        Yii::$app->controller = $controller;
        $result = $controller->runAction($actionID, $params);
        ...
    }
    ...
}


runAction中的流程请参考Yii理解Controller
http://blog.csdn.net/alex_my/article/details/54138744

在yii\base\Controller::runAction中
会执行 this->beforeAction —> this->ensureBehaviors()
将SiteController::behaviors()中的行为绑定到SiteController上

public function ensureBehaviors()
{
    if ($this->_behaviors === null) {
        $this->_behaviors = [];
        foreach ($this->behaviors() as $name => $behavior) {
            $this->attachBehaviorInternal($name, $behavior);
        }
    }
}
private function attachBehaviorInternal($name, $behavior)
{
    if (!($behavior instanceof Behavior)) 
    {
        $behavior = Yii::createObject($behavior);
    }
    if (is_int($name)) 
    {
        $behavior->attach($this);
        $this->_behaviors[] = $behavior;
    } 
    else 
    {
        if (isset($this->_behaviors[$name])) 
        {
            $this->_behaviors[$name]->detach();
        }
        // ---------------- 这个名为access的行为将会执行到这里
        $behavior->attach($this);
        $this->_behaviors[$name] = $behavior;
    }
    return $behavior;
}


$behaviors实际上是AccessControl的对象,attach是其基类ActionFilter中的函数

// yii\base\ActionFilter::attach
public function attach($owner)
{
    $this->owner = $owner;
    $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
}

将会执行ActionFilter::beforeFilter

public function beforeFilter($event)
{
    ...
    $event->isValid = $this->beforeAction($event->action);
    ...
}

AccessControl重载了beforeAction函数

// yii\filters\AccessControl::beforeAction
public function beforeAction($action)
{
    $user = $this->user;
    $request = Yii::$app->getRequest();
    // 这些就是在SiteController中定义的规则
    foreach ($this->rules as $rule) 
    {
        if ($allow = $rule->allows($action, $user, $request)) 
        {
            return true;
        } 
        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 简述

简单的说就是会在执行controller中的action(比如SiteController::actionIndex)之前, 会先执行这些behaviors, 如果没有通过, 则action不会继续执行下去。

相关文章
|
11月前
|
机器学习/深度学习 编解码 人工智能
InternVL3.5多模态大模型开源发布,1B-241B九种尺寸,支持跨平台GUI自动化与矢量图生成
近日,上海人工智能实验室(上海AI实验室)重磅开源发布了多模态大模型书生·万象 InternVL3.5,通过创新的级联式强化学习(Cascade RL)、动态视觉分辨率路由与解耦部署架构,实现推理能力、部署效率与通用能力的全面升级。
2904 7
|
存储 安全 前端开发
OAuth 2.0资源授权机制与安全风险分析
OAuth 2.0资源授权机制与安全风险分析
1044 1
|
JSON API 数据格式
postman如何发送json请求其中file字段是一个图片
postman如何发送json请求其中file字段是一个图片
790 4
|
编解码 定位技术 计算机视觉
多模态LLM视觉推理能力堪忧,浙大领衔用GPT-4合成数据构建多模态基准
【9月更文挑战第2天】浙江大学领衔的研究团队针对多模态大型模型(MLLM)在抽象图像理解和视觉推理上的不足,提出了一种利用GPT-4合成数据构建多模态基准的方法。该研究通过合成数据提高了MLLM处理图表、文档等复杂图像的能力,并构建了一个包含11,193条指令的基准,涵盖8种视觉场景。实验表明,这种方法能显著提升模型性能,但依赖闭源模型和高计算成本是其局限。论文详细内容见:https://arxiv.org/pdf/2407.07053
581 10
|
JavaScript
iframe的父子页面通信
iframe的父子页面通信
883 6
|
存储 监控 安全
ERP系统中的用户权限与安全管理
【7月更文挑战第25天】 ERP系统中的用户权限与安全管理
1307 2
|
自然语言处理 安全 Java
Java演进问题之Substrate VM处理Java序列化如何解决
Java演进问题之Substrate VM处理Java序列化如何解决
320 4
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的宠物美容机构CRM系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的宠物美容机构CRM系统附带文章和源代码部署视频讲解等
227 0
|
Java Maven 数据安全/隐私保护
写给大忙人看的 - Java中图片压缩上传至MinIO服务器(4)
之前文章已经介绍了 MinIO 的环境搭建,已经对文件的上传下载方法,本篇文章一起与大家来学习图片压缩上传的方法
2039 1
写给大忙人看的 - Java中图片压缩上传至MinIO服务器(4)
|
存储 数据挖掘
[Halcon&识别] 二维码识别
[Halcon&识别] 二维码识别
2472 0