欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-29 20:34:31
...

以下分析基于Yii v1.0.6

 

Yii_PATH表示framework的路径

 

通常使用Yii框架的index.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();

 

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

 

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

 

Yii_PATH/YiiBase.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');

 

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

 

Yii_PATH/web/CWebApplication.php

class CWebApplication extends CApplication
{
……
}

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

 

Yii_PATH/base/CApplication.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();
    }
……
}

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

 

Yii::setApplication($this);

 对应代码如下:

    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,继续:

        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,设置成员变量:

    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)));
    }

 之后:

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

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

    public static function setPathOfAlias($alias,$path)
    {
        if(empty($path))
            unset(self::$_aliases[$alias]);
        else
            self::$_aliases[$alias]=rtrim($path,'\\/');
    }

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

$this->preinit();

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

protected function preinit(){
}

 

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