热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Yii分析1:web程序入口(2)

接上篇:Yii分析1:web程序入口(1)然后调用了两个初始化异常/错误和注册核心组件的方法:

接上篇:Yii分析1:web程序入口(1)

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

PHP
$this->initSystemHandlers(); $this->registerCoreComponents();
1
2
    $this->initSystemHandlers();    
    $this->registerCoreComponents();

函数实现如下:

PHP
//初始化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()); }
1
2
3
4
5
6
7
8
    //初始化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的方法:

PHP
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); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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中代码如下:

PHP
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); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    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中:

PHP
/** * 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; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    /**
     * 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;  
        }  
    }

之后这三行代码:

PHP
$this->configure($config); $this->attachBehaviors($this->behaviors); $this->preloadComponents();
1
2
3
    $this->configure($config);  
    $this->attachBehaviors($this->behaviors);  
    $this->preloadComponents();

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

PHP
$this->configure($config);
1
    $this->configure($config);

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

PHP
public function configure($config) { if(is_array($config)) { foreach($config as $key=>$value) $this->$key=$value; } }
1
2
3
4
5
6
7
8
    public function configure($config)  
    {  
        if(is_array($config))  
        {  
            foreach($config as $key=>$value)  
                $this->$key=$value;  
        }  
    }

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

PHP
return array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'blog', 'defaultController'=>'post', …… }
1
2
3
4
5
6
    return array(  
        'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',  
        'name'=>'blog',  
        'defaultController'=>'post',  
    ……  
    }

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

PHP
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))); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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)));  
    }

接下来是:

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

依然调用的CComponent中的方法:

PHP
public function attachBehaviors($behaviors) { foreach($behaviors as $name=>$behavior) $this->attachBehavior($name,$behavior); }
1
2
3
4
5
    public function attachBehaviors($behaviors)  
    {  
        foreach($behaviors as $name=>$behavior)  
            $this->attachBehavior($name,$behavior);  
    }

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

之后是:

PHP
$this->preloadComponents();
1
$this->preloadComponents();

调用的是CModule中的方法:

PHP
protected function preloadComponents() { foreach($this->preload as $id) $this->getComponent($id); }
1
2
3
4
5
protected function preloadComponents()  
{  
    foreach($this->preload as $id)  
        $this->getComponent($id);  
}

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

 

最后调用的方法是:

PHP
$this->init();
1
    $this->init();

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

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

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

PHP
protected function init() { }
1
2
3
    protected function init()  
    {  
    }

没有做任何事

 

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

 

读取配置文件;

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

初始化preload配置的类;

 


推荐阅读
  • 本文详细介绍了IBM DB2数据库在大型应用系统中的应用,强调其卓越的可扩展性和多环境支持能力。文章深入分析了DB2在数据利用性、完整性、安全性和恢复性方面的优势,并提供了优化建议以提升其在不同规模应用程序中的表现。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • Vue 2 中解决页面刷新和按钮跳转导致导航栏样式失效的问题
    本文介绍了如何通过配置路由的 meta 字段,确保 Vue 2 项目中的导航栏在页面刷新或内部按钮跳转时,始终保持正确的 active 样式。具体实现方法包括设置路由的 meta 属性,并在 HTML 模板中动态绑定类名。 ... [详细]
  • SQL中UPDATE SET FROM语句的使用方法及应用场景
    本文详细介绍了SQL中UPDATE SET FROM语句的使用方法,通过具体示例展示了如何利用该语句高效地更新多表关联数据。适合数据库管理员和开发人员参考。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 如何在PHPcms网站中添加广告
    本文详细介绍了在PHPcms网站后台添加广告的方法,涵盖多种常见的广告形式,如百度广告和Google广告,并提供了相关设置的步骤。同时,文章还探讨了优化网站流量的SEO策略。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
author-avatar
傻a2602909381
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有