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

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

Yii其实是YiiBase的helper,因此我们实际查看的是YiiBase::CreateWebApplication

以下分析基于Yii v1.0.6

 

Yii_PATH表示framework的路径

 

通常使用Yii框架的index.php程序如下:

PHP
// change the following paths if necessary $yii = dirname(__FILE__).'/protected/lib/Yii/framework/yii.php'; $cOnfig= dirname(__FILE__).'/protected/config/main.php'; // remove the following line when in production mode defined('YII_DEBUG') or define('YII_DEBUG',true); require_once $yii; $app = Yii::CreateWebApplication($config); $app->run();
1
2
3
4
5
6
7
8
9
10
// change the following paths if necessary
$yii    = dirname(__FILE__).'/protected/lib/Yii/framework/yii.php';
$cOnfig= dirname(__FILE__).'/protected/config/main.php';
 
// remove the following line when in production mode
defined('YII_DEBUG') or define('YII_DEBUG',true);
 
require_once $yii;
$app = Yii::CreateWebApplication($config);
$app->run();


我们来看一下Yii::CreateWebApplication的过程:

 

Yii其实是YiiBase的helper,因此我们实际查看的是YiiBase::CreateWebApplication

 

Yii_PATH/YiiBase.php:

PHP
class YiiBase { …… public static function createWebApplication($cOnfig=null) { return new CWebApplication($config); } …… //自动类加载函数 public static function autoload($className) { // use include so that the error PHP file may appear if(isset(self::$_coreClasses[$className])) include(YII_PATH.self::$_coreClasses[$className]); else if(isset(self::$_classes[$className])) include(self::$_classes[$className]); else { include($className.'.php'); return class_exists($className,false) || interface_exists($className,false); } return true; } …… //核心类列表 private static $_coreClasses=array( 'CApplication' => '/base/CApplication.php', 'CApplicationComponent' => '/base/CApplicationComponent.php', 'CBehavior' => '/base/CBehavior.php', …… ); } //注册自动类加载函数 spl_autoload_register(array('YiiBase','autoload')); require(YII_PATH.'/base/interfaces.php');
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
    class YiiBase  
    {  
    ……  
        public static function createWebApplication($cOnfig=null)  
        {  
            return new CWebApplication($config);  
        }  
    ……  
        //自动类加载函数  
        public static function autoload($className)  
        {  
 
            // use include so that the error PHP file may appear  
            if(isset(self::$_coreClasses[$className]))  
                include(YII_PATH.self::$_coreClasses[$className]);  
            else if(isset(self::$_classes[$className]))  
                include(self::$_classes[$className]);  
            else  
            {  
                include($className.'.php');  
                return class_exists($className,false) || interface_exists($className,false);  
            }  
            return true;  
        }  
    ……  
 
        //核心类列表  
        private static $_coreClasses=array(  
            'CApplication' => '/base/CApplication.php',  
            'CApplicationComponent' => '/base/CApplicationComponent.php',  
            'CBehavior' => '/base/CBehavior.php',  
            ……  
        );  
 
    }  
    //注册自动类加载函数  
    spl_autoload_register(array('YiiBase','autoload'));  
    require(YII_PATH.'/base/interfaces.php');

 

这里返回的是一个CWebApplication的对象,

 

Yii_PATH/web/CWebApplication.php

PHP
class CWebApplication extends CApplication { …… }
1
2
3
4
    class CWebApplication extends CApplication  
    {  
    ……  
    }

CWebApplication继承自CApplication,没有自定义的constructor,因此我们继续查看CApplication的constructor:

 

Yii_PATH/base/CApplication.php

PHP
abstract class CApplication extends CModule { …… public function __construct($cOnfig=null) { Yii::setApplication($this); // set basePath at early as possible to avoid trouble if(is_string($config)) $cOnfig=require($config); if(isset($config['basePath'])) { $this->setBasePath($config['basePath']); unset($config['basePath']); } else $this->setBasePath('protected'); Yii::setPathOfAlias('application',$this->getBasePath()); Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME'])); $this->preinit(); $this->initSystemHandlers(); $this->registerCoreComponents(); $this->configure($config); $this->attachBehaviors($this->behaviors); $this->preloadComponents(); $this->init(); } …… }
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
    abstract class CApplication extends CModule  
    {  
    ……  
        public function __construct($cOnfig=null)  
        {  
            Yii::setApplication($this);  
            // set basePath at early as possible to avoid trouble  
            if(is_string($config))  
                $cOnfig=require($config);  
            if(isset($config['basePath']))  
            {  
                $this->setBasePath($config['basePath']);  
                unset($config['basePath']);  
            }  
            else  
                $this->setBasePath('protected');  
            Yii::setPathOfAlias('application',$this->getBasePath());  
            Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));  
 
            $this->preinit();  
 
            $this->initSystemHandlers();  
            $this->registerCoreComponents();  
 
            $this->configure($config);  
            $this->attachBehaviors($this->behaviors);  
            $this->preloadComponents();  
 
            $this->init();  
        }  
    ……  
    }

这里,做了很多工作,我们来慢慢分析:

PHP
Yii::setApplication($this);
1
Yii::setApplication($this);

 

PHP
public static function setApplication($app) { if(self::$_app===null || $app===null) self::$_app=$app; else throw new CException(Yii::t('yii','Yii application can only be created once.')); }
1
2
3
4
5
6
7
    public static function setApplication($app)  
    {  
        if(self::$_app===null || $app===null)  
            self::$_app=$app;  
        else  
            throw new CException(Yii::t('yii','Yii application can only be created once.'));  
    }

这里只是set一下application的名称,ok,继续:

PHP
if(is_string($config)) $cOnfig=require($config); if(isset($config['basePath'])) { $this->setBasePath($config['basePath']); unset($config['basePath']); } else $this->setBasePath('protected');
1
2
3
4
5
6
7
8
9
    if(is_string($config))  
        $cOnfig=require($config);  
    if(isset($config['basePath']))  
    {  
        $this->setBasePath($config['basePath']);  
        unset($config['basePath']);  
    }  
    else  
        $this->setBasePath('protected');

这里主要是将createWebApplication时穿过来的配置文件require了一下,然后拿到配置项中的basePath,设置成员变量:

PHP
public function setBasePath($path) { if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath)) throw new CException(Yii::t('yii','Application base path "{path}" is not a valid directory.', array('{path}'=>$path))); }
1
2
3
4
5
6
    public function setBasePath($path)  
    {  
        if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))  
            throw new CException(Yii::t('yii','Application base path "{path}" is not a valid directory.',  
                array('{path}'=>$path)));  
    }

之后:

PHP
Yii::setPathOfAlias('application',$this->getBasePath()); Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));
1
2
    Yii::setPathOfAlias('application',$this->getBasePath());  
    Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));

通过下面的函数设置路径的别名:

PHP
public static function setPathOfAlias($alias,$path) { if(emptyempty($path)) unset(self::$_aliases[$alias]); else self::$_aliases[$alias]=rtrim($path,'\\/'); }
1
2
3
4
5
6
7
    public static function setPathOfAlias($alias,$path)  
    {  
        if(emptyempty($path))  
            unset(self::$_aliases[$alias]);  
        else  
            self::$_aliases[$alias]=rtrim($path,'\\/');  
    }

保存在$_aliases数组中,接下来是一些初始化的工作(未完待续):

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

调用的是Yii_PATH/base/CModule.php中的一个空函数,用于初始化模块(子类覆盖)

PHP
protected function preinit(){ }
1
2
protected function preinit(){  
}

推荐阅读
  • 随着科技的进步,AR智能眼镜正逐渐成为日常生活的一部分。今年冬天,一款仅重38克的AR智能眼镜成为了市场上的焦点,其超轻设计和创新功能值得我们深入了解。 ... [详细]
  • 本文探讨了如何在C#应用程序中有效处理来自两个不同数据库的数据,特别是当需要从一个数据库中选择不在另一个大型集合中的ID时遇到的挑战和解决方案。 ... [详细]
  • Java 动态代理详解与示例
    本文详细介绍了Java中的动态代理机制,包括如何定义接口、实现类和代理处理器,并通过具体示例演示了动态代理的创建和使用过程。 ... [详细]
  • LeetCode 6057: 计算与子树平均值相等的节点数量——深度优先搜索
    本题要求在给定的二叉树中找到所有符合条件的节点数量,即节点的值等于其所有后代节点(包括自身)值的平均值。这里的平均值是通过将所有后代节点值之和除以后代节点的数量,并向下取整得到。 ... [详细]
  • CSGO
    CSGOTimeLimit:40002000MS(JavaOthers)MemoryLimit:524288524288K(JavaOthers)ProblemDescriptio ... [详细]
  • 本文介绍了如何通过自定义View中的declare-styleable属性创建枚举类型,并在代码中访问这些枚举值的方法。 ... [详细]
  • 本文汇集了使用C#中不同HTTP客户端向Web API上传文件的实例,旨在为开发者提供实用的技术指南。 ... [详细]
  • 本文详细介绍了在PHP中如何创建新文件以及如何使自定义函数在整个项目中全局可用的方法,包括最新的实践技巧。 ... [详细]
  • 解决Android开发中的TextView难题
    探讨了在Android开发过程中遇到的关于TextView组件的常见问题,特别是如何实现多行文字的跑马灯效果,并提供了初步的解决方案和参考资料。 ... [详细]
  • Only2 Labs 是一家专注于视觉设计的工作室,如果您对当前的设计感到不满,或者急需寻找一个可靠的设计合作伙伴,甚至是您的团队项目需要专业指导,Only2 Labs 都将竭诚为您提供帮助。 ... [详细]
  • 解决phpMyAdmin运行错误:mysqli_init(): 属性访问尚未允许
    本文探讨了在使用phpMyAdmin过程中遇到的mysqli_init()函数错误,并提供了有效的解决方案。 ... [详细]
  • 本文探讨了Windows Presentation Foundation (WPF)如何通过扩展Microsoft Build Engine (MSBuild)来增强其构建能力,特别是在处理WPF特有的任务时。 ... [详细]
  • 本文探讨了在执行SQL查询时遇到的因字符集不同而导致查询结果差异的问题,特别是涉及中文字符时。文章分析了在不同字符集设置下,SQL查询结果的变化,并提供了详细的解决方案。 ... [详细]
  • 本文探讨了如何在JavaScript中调用PHP函数及实现两者之间的有效交互,包括通过AJAX请求、动态生成JavaScript代码等方法。 ... [详细]
  • 深入解析PHP Xdebug的安装与应用
    本文详细介绍了PHP Xdebug的安装步骤及其在PHP开发中的重要作用。Xdebug作为一款强大的调试工具,不仅能够帮助开发者追踪代码执行过程,还能有效提升代码质量和系统性能。 ... [详细]
author-avatar
ID张蕾
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有