yii 框架源码阅读(二) - 整体执行流程分析

一  程序入口

<?php

// change the following paths if necessary
$yii=dirname(__FILE__).'/http://www.cnblogs.com/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);
Yii::createWebApplication($config)->run();
require_once($yii) 语句包含了yii.php 文件,该文件是Yii bootstrap file,包含了 yiibase的基础类,yii完全继承了yiibase
<?php
/**
* Yii bootstrap file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
* @version $Id: yii.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system
* @since 1.0
*/

require(dirname(__FILE__).'/YiiBase.php');

/**
* Yii is a helper class serving common framework functionalities.
*
* It encapsulates {@link YiiBase} which provides the actual implementation.
* By writing your own Yii class, you can customize some functionalities of YiiBase.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: yii.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system
* @since 1.0
*/
class Yii extends YiiBase
{
}
在 YiiBase 类中 定义了一些 比如:
public static function createWebApplication($config=null) // 创建启动

public static function import($alias,$forceInclude=false) // 类导入

public static function createComponent($config) // 创建组件

public static function setApplication($app) // 创建类的实例 yii::app()

二 自动加载机制


还有比较重要的yii自动加载机制,在yiibase的最后引用了php的标准库函数 spl_autoload_register(array('YiiBase','autoload')) 调用框架中的autoload方法

/**
* Class autoload loader.
* This method is provided to be invoked within an __autoload() magic method.
* @param string $className class name
* @return boolean whether the class has been loaded successfully
*/
public static function autoload($className)
{
// use include so that the error PHP file may appear
if(isset(self::$classMap[$className]))
include(self::$classMap[$className]);
else if(isset(self::$_coreClasses[$className]))
include(YII_PATH.self::$_coreClasses[$className]);
else
{
// include class file relying on include_path
if(strpos($className,'\\')===false) // class without namespace
{
if(self::$enableIncludePath===false)
{
foreach(self::$_includePaths as $path)
{
$classFile=$path.DIRECTORY_SEPARATOR.$className.'.php';
if(is_file($classFile))
{
include($classFile);
break;
}
}
}
else
include($className.'.php');
}
else // class name with namespace in PHP 5.3
{
$namespace=str_replace('\\','.',ltrim($className,'\\'));
if(($path=self::getPathOfAlias($namespace))!==false)
include($path.'.php');
else
return false;
}
return class_exists($className,false) || interface_exists($className,false);
}
return true;
}

静态成员 $_coreClasses 变量中定义了一些系统自身的核心类
private static $_coreClasses=array(
'CApplication' => '/base/CApplication.php',
'CApplicationComponent' => '/base/CApplicationComponent.php',
'CBehavior' => '/base/CBehavior.php',
'CComponent' => '/base/CComponent.php',

非 coreClasse 的类注册在YiiBase的$_classes 数组中:  

private static $_classes=array();  

   

其他的类需要用Yii::import()讲类路径导入PHP include paths 中,直接  

include($className.'.php') 


三 CWebApplication的创建 

Yii::createWebApplication($config)->run(); 调用createWebApplication函数

public static function createWebApplication($config=null)
{
return self::createApplication('CWebApplication',$config); // 函数中调用createApplication

}

public static function createApplication($class,$config=null)
{
return new $class($config);
}
返回 CWebApplication类的实例 

现在autoload机制开始工作了。  

当系统 执行 new CWebApplication() 的时候,会自动  

include(YII_PATH.'/base/CApplication.php') 

几个类的继承关系是 CWebApplication->CApplication->CModule->CComponent

$config 首先传递到CApplication的构造函数中,
public function __construct($config=null)
{
Yii::setApplication($this); // 返回自身的实例,之后可以通过 yii::app() 全局调用

// 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'); // 设置路径 指向protected 目录
Yii::setPathOfAlias('application',$this->getBasePath());
Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));
Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');

$this->preinit();

$this->initSystemHandlers(); 设置error 和 exception
$this->registerCoreComponents(); 注册核心组件,放入_componentConfig 静态变量中

$this->configure($config); // 把配置文件数组循环,设置为自身属性
$this->attachBehaviors($this->behaviors); // 设置行为
$this->preloadComponents(); // 预加载

$this->init(); // 加载请求处理模块,开始处理请求
}

大概过程  

application构造函数:  

1 设置当前运行实例  

2 获取配置参数  

3 设置basepath  

4 设置几个path;application,webroot ,ext  

5 preinit  

6 注册error、exception处理函数 initSystemHandlers  

7 加载核心组件 registerCoreComponents 包括webapplication的和application的  

8 设置配置文件 configure($config)  

9 附加行为 $this->attachBehaviors($this->behaviors);  

10处理加载config中的preload,//通过getComponent分别加载并初始化 $this->preloadComponents();   

11 初始化init(); //加载CHttpRequest组件 






posted on 2012-04-03 11:24  mashuaimama  阅读(907)  评论(0编辑  收藏  举报

导航