博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Yii分析1:web程序入口(2)
阅读量:4079 次
发布时间:2019-05-25

本文共 6914 字,大约阅读时间需要 23 分钟。

 

接上篇:

 

然后调用了两个初始化异常/错误和注册核心组件的方法:

$this->initSystemHandlers();           $this->registerCoreComponents();

 函数实现如下:

//初始化errorhandler和exceptionhandler    protected function initSystemHandlers()    {        if(YII_ENABLE_EXCEPTION_HANDLER)            set_exception_handler(array($this,'handleException'));        if(YII_ENABLE_ERROR_HANDLER)            set_error_handler(array($this,'handleError'),error_reporting());    }

 registerCoreComponents调用了CWebApplication的方法:

protected function registerCoreComponents()    {        parent::registerCoreComponents();        $components=array(                                //url路由类            'urlManager'=>array(                                                                  'class'=>'CUrlManager',                                                       ),                         //http请求处理类            'request'=>array(                'class'=>'CHttpRequest',                                                      ),            //session处理类            'session'=>array(                'class'=>'CHttpSession',                                                      ),              //assets文件管理类            'assetManager'=>array(                                                                'class'=>'CAssetManager',                                                     ),                                      //用户类            'user'=>array(                                                                        'class'=>'CWebUser',            ),            //主题管理类            'themeManager'=>array(                'class'=>'CThemeManager',            ),            //认证管理类            'authManager'=>array(                'class'=>'CPhpAuthManager',            ),             //客户端脚本管理类            'clientScript'=>array(                'class'=>'CClientScript',            ),        );        $this->setComponents($components);    }

 其中CWebApplication的parent中代码如下:

protected function registerCoreComponents()    {        $components=array(            //消息类(国际化)            'coreMessages'=>array(                'class'=>'CPhpMessageSource',                'language'=>'en_us',                'basePath'=>YII_PATH.DIRECTORY_SEPARATOR.'messages',            ),            //数据库类            'db'=>array(                'class'=>'CDbConnection',            ),            'messages'=>array(                'class'=>'CPhpMessageSource',            ),            //错误处理            'errorHandler'=>array(                'class'=>'CErrorHandler',            ),            //安全处理类            'securityManager'=>array(                'class'=>'CSecurityManager',            ),            //基于文件的持久化存储类            'statePersister'=>array(                'class'=>'CStatePersister',            ),        );        $this->setComponents($components);    }

setComponents定义在CModule中:

/**     * Sets the application components.     *     * When a configuration is used to specify a component, it should consist of     * the component's initial property values (name-value pairs). Additionally,     * a component can be enabled (default) or disabled by specifying the 'enabled' value     * in the configuration.     *     * If a configuration is specified with an ID that is the same as an existing     * component or configuration, the existing one will be replaced silently.     *     * The following is the configuration for two components:     * 
     * array(     *     'db'=>array(     *         'class'=>'CDbConnection',     *         'connectionString'=>'sqlite:path/to/file.db',     *     ),     *     'cache'=>array(     *         'class'=>'CDbCache',     *         'connectionID'=>'db',     *         'enabled'=>!YII_DEBUG,  // enable caching in non-debug mode     *     ),     * )     * 
* * @param array application components(id=>component configuration or instances) */ public function setComponents($components) { foreach($components as $id=>$component) { //如果继承了IApplicationComponent,则立即set,否则放进_componentConfig数组中 if($component instanceof IApplicationComponent) $this->setComponent($id,$component); else if(isset($this->_componentConfig[$id])) $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component); else $this->_componentConfig[$id]=$component; } }
 

 

之后这三行代码:

$this->configure($config);        $this->attachBehaviors($this->behaviors);        $this->preloadComponents();

 每一行都做了很多工作,我们一步一步分析:

 

$this->configure($config);

 CApplication并没有configure方法,因此我们查看父类CModule的configure方法:

public function configure($config)    {        if(is_array($config))        {            foreach($config as $key=>$value)                $this->$key=$value;        }    }

 是否还记得$config这个变量?其实它是一个数组包含了一些基本配置信息,例如(yii自带blog demo):

return array(    'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',    'name'=>'blog',    'defaultController'=>'post',……}

 configure看起来仅仅是将数组的键值对赋值给类的变量和值,其实这里使用了__set方法,而CModule并没有__set方法,因此看他的父类CComponent:

public function __set($name,$value)    {        $setter='set'.$name;         //如果set开头的方法存在,则调用set方法进行赋值        if(method_exists($this,$setter))            $this->$setter($value);                 //如果有on开通的事件函数,则调用该事件函数处理        else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))        {            // duplicating getEventHandlers() here for performance            $name=strtolower($name);            if(!isset($this->_e[$name]))                $this->_e[$name]=new CList;            $this->_e[$name]->add($value);        }          //如果只存在get方法,那么说明这个属性是制度的,抛出异常         else if(method_exists($this,'get'.$name))            throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',                array('{class}'=>get_class($this), '{property}'=>$name)));                   //否则抛出异常        else                        throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',                array('{class}'=>get_class($this), '{property}'=>$name)));    }
 

接下来是:

$this->attachBehaviors($this->behaviors);

 依然调用的CComponent中的方法:

public function attachBehaviors($behaviors)    {        foreach($behaviors as $name=>$behavior)            $this->attachBehavior($name,$behavior);    }

 事实上,这里$this->behavior还是空的,因此这里并没有做什么事情;

 

之后是:

$this->preloadComponents();

 调用的是CModule中的方法:

protected function preloadComponents()    {        foreach($this->preload as $id)            $this->getComponent($id);    }

 是否还记得config会配置一个键名为'preload‘的数组成员?在这里会将其中的类初始化;

 

最后调用的方法是:

$this->init();

首先调用了CWebApplication中的init方法:

protected function init()    {        parent::init();        // preload 'request' so that it has chance to respond to onBeginRequest event.        $this->getRequest();    }
 

其中调用了父类的父类CModule中的方法init:

protected function init()    {    }

 没有做任何事

 

到这里,new CreateWebApplication的工作全部完成,主要过程总结如下:

 

读取配置文件;

将配置文件中的数组成员赋值给成员变量;

初始化preload配置的类;

 

 

(未完待续)

 

 

 

 

 

转载地址:http://rtsni.baihongyu.com/

你可能感兴趣的文章
吃透tensorflow那本书里面的LSTM那个程序
查看>>
今天初步装好了我的猛禽360机架
查看>>
一稿多投被拒稿,确实是你的错
查看>>
碳机架是导电的
查看>>
PID在线调参这个方法不错!!!!!这可以让PID调参方便很多啊!!!!!!!而且可以很方便看到各个参数变化造成的影响!!!!!!!
查看>>
自平衡自行车本质就是一个惯性飞轮,本质就是一样的!!!
查看>>
自平衡立方体的动力学建模用到了拉格朗日方法,让我想起无人机的动力学建模也用到了拉格朗日方法。
查看>>
单点自平衡立方体相当于有几个自由度?自平衡自行车有几个自由度?独轮车有几个自由度?
查看>>
不要迷信STM32cube,有的例程都跑不起来。
查看>>
cubli我觉得不管是工作还是读研发文章还是读博,都用得到,我觉得可以弄弄。
查看>>
当初校赛智能车是这么实现用按键更改PID参数的
查看>>
当初校赛智能车的程序我还是有保存一些的。
查看>>
semaphore就是信号量的意思,以后看见信号量相关的函数不用怕,函数命名都是有规则的,查词典就可以了。
查看>>
一些信号量的函数里面其实就是调用的消息队列的函数实现的!怪不得华清的老师说先讲消息队列其他都弄懂了。
查看>>
ACfly工程Freertos层面上解析
查看>>
Python并非为AI而生,Golang将统治人工智能的下一个十年?
查看>>
每获取一次信号量就对应着要释放一次信号量,这也是为什么你在ACfly工程里面看到这么多次释放信号量的原因。
查看>>
真正面试的底气还是来自于你真正吃透了几本书几个东西,而不是几个高大上的项目。
查看>>
互斥信号量和二值信号量的区别在于优先级翻转,注意了,有区别,之前一直以为差不多。
查看>>
我目前觉得嵌入式面试(STM32方向)需要准备的一些东西
查看>>