您的位置:首页 > 编程语言 > PHP开发

Yii请求处理流程分析

2009-07-12 11:38 627 查看
近日对Yii的请求处理有些疑惑~所以便开始了对Yii的源码的研究.



Yii请求处理流程图

这是官方的一副流程图.
打开源码~开始了请求的追踪.

当一次请求被处理的时候~程序先调用了project/index.php文件,里面有如下几行代码:

?[Copy to clipboard]View Code PHP

1
2
3
4
5
6
7
8
9

// change the following paths if necessary
$yii=dirname(__FILE__).'/../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);
Yii::createWebApplication($config)->run();

这段代码首先讲yii.php文件和main.php文件放入2个变量中,然后设置了YII_DEBUG变量为true,接着require_once了yii.php文件,并调用了run()方法.

yii.php文件有如下代码:

?[Copy to clipboard]View Code PHP

1
2
3
4

require(dirname(__FILE__).'/YiiBase.php');
class Yii extends YiiBase
{
}

这段代码导入了yiibase.php,并定义了类Yii,该类继承YiiBase.

main.php里面是各种配置的信息,将配置信息作为数组返回.
Yii继承YiiBase,于是又找到YiiBase.php文件,发现这个文件开始的时候定义了如下几个变量:YII_BEGIN_TIME,YII_DEBUG,YII_ENABLE_EXCEPTION_HANDLER,YII_ENABLE_ERROR_HANDLER和YII_BATH.
找到createWebApplication方法,里面就一条语句:

?[Copy to clipboard]View Code PHP

1

return new CWebApplication($config);

于是又找到yii/framework/web/CWebApplication.php文件,但是却没有在里面找到构造函数,由于该类继承CApplication,又找到yii/framework/base/CApplication.php,这个类里有构造函数,内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
4
5
6
7
8
910
1112
13
14
15
16
17
18
19
20
2122
23
24
25
26
27
28

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($app);调用YiiBase里的setApplication()方法,该方法内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
45
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.'));
}

这个方法的目的是实例化一个app对象.
第6行到第14行设定了config和basePath.第15句和第16句设定了2个路径的快捷方式, webroot和application.
第18行调用了preinit()方法,该方法在该类中没有,是该类的父类CModule里的,但是找到yii/framework/base/CModule.php后,发现该方法内容为空.
第20行调用了initSystemHandlers,该方法位于该类中,内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
45
6
7

protected function initSystemHandlers()
{
if(YII_ENABLE_EXCEPTION_HANDLER)
set_exception_handler(array($this,'handleException'));
if(YII_ENABLE_ERROR_HANDLER)
set_error_handler(array($this,'handleError'),error_reporting());
}

第21行调用了registerCoreComponents方法,该方法内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
4
5
6
7
8
910
1112
13
14
15
16
17
18
19
20
2122
23
24
25
26
27

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',
),
);

$this->setComponents($components);
}

第23行调用了configure方法,该方法在父类CModule里,内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
45
6
7
8

public function configure($config)
{
if(is_array($config))
{
foreach($config as $key=>$value)
$this->$key=$value;
}
}

第24行调用了attachBehaviors方法,该方法位于父类CModule的父类CComponent类中,内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
45

public function attachBehaviors($behaviors)
{
foreach($behaviors as $name=>$behavior)
$this->attachBehavior($name,$behavior);
}

第25行调用了preloadComponents方法,该方法同样位于父类CModule里,内容如下:

?[Copy to clipboard]View Code PHP

1
2
3
45

protected function preloadComponents()
{
foreach($this->preload as $id)
$this->getComponent($id);
}

第27行调用了init方法,该方法位于父类CModule方法中,内容为空.
至此Yii::createWebApplication($config)方法已经分析完成~剩下的就是run()方法了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: