• Yii请求处理流程分析


    近日对Yii的请求处理有些疑惑~所以便开始了对Yii的源码的研究.

     

    Yii请求处理流程图


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

    当一次请求被处理的时候~程序先调用了project/index.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文件有如下代码:

    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方法,里面就一条语句:

    1
    
    return new CWebApplication($config);

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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()方法,该方法内容如下:

    1
    2
    3
    4
    5
    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,该方法位于该类中,内容如下:

    1
    2
    3
    4
    5
    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方法,该方法内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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里,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    
    public function configure($config)
    {
    	if(is_array($config))
    	{
    		foreach($config as $key=>$value)
    			$this->$key=$value;
    	}
    }

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

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

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

    1
    2
    3
    4
    5
    
    protected function preloadComponents()
    {
    	foreach($this->preload as $id)
    		$this->getComponent($id);
    }

    第27行调用了init方法,该方法位于父类CModule方法中,内容为空.
    至此Yii::createWebApplication($config)方法已经分析完成~剩下的就是run()方法了.

    aliyun活动 https://www.aliyun.com/acts/limit-buy?userCode=re2o7acl
  • 相关阅读:
    PLSQL游标
    SqlHelper助手
    机房重构前奏——三层转七层
    应用运筹管理经济
    C++——宏观把控
    操作系统——宏观把控
    .NET总结一
    深复制与浅复制
    设计模式之结构型
    设计模式之一对多
  • 原文地址:https://www.cnblogs.com/wangbin/p/1521885.html
Copyright © 2020-2023  润新知