热门标签 | 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配置的类;

 


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 信息安全等级保护是指对国家秘密信息、法人和其他组织及公民的专有信息以及公开信息和存储、传输、处理这些信息的信息系统分等级实行安全保护,对信息系统中使用的信息安全产品实 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
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社区 版权所有