//定义yii.php的相对位置
$yii=dirname(__FILE__).'/../yii/framework/yii.php';
//设置加载配置文件路径
$config=dirname(__FILE__).'/protected/config/main.php';
//开启调试
defined('YII_DEBUG') or define('YII_DEBUG',true);
//追踪级别
defined('YII_TRACE_LEVEL') or
define('YII_TRACE_LEVEL',3);
//包含yii.php,并使用其中的Yii类初始化入口
require_once($yii);
yii.php:
require(dirname(__FILE__).'/YiiBase.php');
//YiiBase.php结尾的自动注册类,被包含时自动执行
spl_autoload_register(array('YiiBase','autoload'));
require(YII_PATH.'/base/interfaces.php');
class Yii extends YiiBase{}
//初次化入口
Yii::createWebApplication($config)->run();//index.php文件结束
↓
YiiBase.php
public static function createWebApplication($config=null){
return
self::createApplication('CWebApplication',$config);}
public static function createApplication($class,$config=null){
//return
new CWebApplication($conf);
return new $class($config);}
加载CWebApplication.php
(依次加载)继承父类:CWebApplication
-> CApplication -> CModule
-> CComponent
$config被传递给CApplication的构造函数
CApplication.php
public function __construct($config=null){
//把当前CWebApplication的实例保存到Yii::$_app,以后可以通过Yii::app()获得
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.')); }
if(is_string($config))
//引入配置文件
$config=require($config);
if(isset($config['basePath'])){
//把配置文件中basePath的值传递给CWebApplication->_basePath
$this->setBasePath($config['basePath']);
配置文件mian.php的上一层目录,为'basePath'
return
array('basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',)
realpath()返回绝对路径,is_dir()判断是否为目录
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)));}
unset($config['basePath']);
}else
//默认basePath目录即为"protected"
$this->setBasePath('protected');
//设置应用目录
'application',保存到YiiBase::$_aliases数组中
Yii::setPathOfAlias('application',$this->getBasePath());
//设置根目录目录
'webroot',保存到YiiBase::$_aliases数组中
Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));
//设置扩展目录
'ext',保存到YiiBase::$_aliases数组中
Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');
//设置系统目录,后面再import的时候可以用别名来代替实际的完整路径
public static function
setPathOfAlias($alias,$path){
if(empty($path))
unset(self::$_aliases[$alias]);
else
//删除右边的'\'或'/',并保存到YiiBase::$_aliases数组中
self::$_aliases[$alias]=rtrim($path,'\\/');}
//调用父类函数CModule->preinit
预初始化,执行空操作
$this->preinit();
protected function preinit(){
}
//自定义错误/异常函数
$this->initSystemHandlers();
protected function
initSystemHandlers(){
//YiiBase定义的常数
if(YII_ENABLE_EXCEPTION_HANDLER)
//自定义异常处理函数
CWebApplication->handlerException($e);
//Yii源码分析-异常处理
set_exception_handler(array($this,'handleException'));
if(YII_ENABLE_ERROR_HANDLER)
//自定义错误处理函数
CWebApplication->handleError($e)
//Yii源码分析-错误处理
set_error_handler(array($this,'handleError'),error_reporting());}
//注册核心组建,先注册CApplication,然后注册CWebApplication定义的组件
$this->registerCoreComponents();
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',),
'urlManager'=>array('class'=>'CUrlManager',),
'request'=>array('class'=>'CHttpRequest',),
'format'=>array('class'=>'CFormatter',),);
$this->setComponents($components);}
public function
setComponents($components,$merge=true){
foreach($components as
$id=>$component){
//IApplicationComponent是所有组件必须实现的接口
if($component instanceof
IApplicationComponent)
//添加一个组件到模块中
$this->setComponent($id,$component);
else
if(isset($this->_componentConfig[$id])
&& $merge)
//覆盖已定义的组件
$this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);
else
//把组件保存到私有变量CFormModel->_componentConfig中,
//初始化时并不加载
$this->_componentConfig[$id]=$component;}}
//为模块指定配置
$this->configure($config);
//CModule
public function
configure($config){
if(is_array($config)){
foreach($config as $key=>$value)
$this->$key=$value;
}}
//如果key未定义,自动调用父类CComponent的魔法函数__set
CModule::setImport
CModule::setModule
Cmodule::setComponents
//添加行为列表到组件,默认为空
$this->attachBehaviors($this->behaviors);
//CComponent
public function
attachBehaviors($behaviors){
foreach($behaviors
as
$name=>$behavior)
$this->attachBehavior($name,$behavior);}
//加载静态应用到组建
$this->preloadComponents();
//CModule
protected function
preloadComponents(){
foreach($this->preload
as
$id)
$this->getComponent($id);}
//CModule
//检索组件,如果不存在则创建
public
function getComponent($id,$createIfNull=true){
if(isset($this->_components[$id]))
return
$this->_components[$id];
else
if(isset($this->_componentConfig[$id])
&& $createIfNull){
$config=$this->_componentConfig[$id];
if(!isset($config['enabled']) ||
$config['enabled']){
Yii::trace("Loading \"$id\"
application component",'system.CModule');
unset($config['enabled']);
$component=Yii::createComponent($config);
$component->init();
return
$this->_components[$id]=$component;}}}
//初始化应用组件,每次加载组建都会运行一次
$this->init();
//CModule
protected function init(){}
↓
执行CWebApplication->run()
//CApplication
//运行应用程序,加载静态组件
public function
run(){
if($this->hasEventHandler('onBeginRequest'))
$this->onBeginRequest(new
CEvent($this));
$this->processRequest();
if($this->hasEventHandler('onEndRequest'))
$this->onEndRequest(new
CEvent($this));}