关于Yii2 Application初始化

Yii框架 · Fecmall · 于 4年前 发布 · 2127 次阅读

在yii2初始化,进行组件初始化的部分,一直没看懂到底是怎么给组件进行数据初始化的,琢磨了几个小时,终于看明白了,其中一个部分纠结了我几个小时,现在已经明白,分享一下:

首先代码:

yii/base/Application.php

public function __construct($config = [])
    {
        Yii::$app = $this;
        static::setInstance($this);

        $this->state = self::STATE_BEGIN;

        $this->preInit($config);

        $this->registerErrorHandler($config);

        Component::__construct($config);
    }

发现组件的配置注入初始化发生在代码Component::__construct($config); (通过调用Yii::$app->db,发现在Component::__construct($config)之后可以调用,之前不能调用,因此就是这个代码进行的配置注入)

2.打开yii\base\Component ,发现该类继承于 yii\base\BaseObject

public function __construct($config = [])
    {
        if (!empty($config)) {
            Yii::configure($this, $config);
        }
        $this->init();
    }

3.查看Yii::configure

public static function configure($object, $properties)
    {
        foreach ($properties as $name => $value) {
            $object->$name = $value;
        }

        return $object;
    }

通过上面代码,$object就是yii\base\Component,会认为这个方法是给yii\base\Component set数据,

4.打开yii\base\Component

public function __set($name, $value)
    {
        var_dump($this);
		$setter = 'set' . $name;
        if (method_exists($this, $setter)) {
            // set property
            $this->$setter($value);

            return;
        } elseif (strncmp($name, 'on ', 3) === 0) {
            // on event: attach event handler
            $this->on(trim(substr($name, 3)), $value);

            return;
        } elseif (strncmp($name, 'as ', 3) === 0) {
            // as behavior: attach behavior
            $name = trim(substr($name, 3));
            $this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value));

            return;
        }

在这个函数里面打印$this,发现不是yii/base/compoent,而是yii/web/Application,顿时,脑袋懵逼了,这NM的啥原因,这是什么操作?

各种方式找原理,终于找到,原因为:

yii/web/application 继承于 yii/base/Module 继承于 yii/di/ServiceLocator 继承于 yii\base\Component;

也就是 yii\base\Componentyii/web/application的祖宗类,如果在十八代孙子类里面想要用祖宗的方法, 那么就通过 Component::__construct($config);,跨17代爷爷辈,直接引入过来祖宗,然后调用,而在祖宗类中的$this,还是十八代孙子,也就是上面打印出来类为 yii/web/application

那么,后面就不难理解了

yii/di/ServiceLocator ,进行数据初始化。

共收到 1 条回复
Fecmall#14年前 0 个赞

研究这个,是为了解决在线安装插件的问题

文件配置和数据库配置,在初始化组件的时候,先初始化db component,然后将数据库中取出来的配置数组配置文件数组进行合并, 然后再初始化其他的组件component和其他配置

添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
Your Site Analytics