以下分析基于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)