yii framework(一)入口分析

既然说YII框架,就从程序入口开始会说吧。下面是网站唯一入口index.php代码:

  1. <?php  
  2. // change the following paths if necessary  
  3. $yii=dirname(__FILE__).'/framework/yii.php';  
  4. $config=dirname(__FILE__).'/protected/config/main.php';  
  5.   
  6. // remove the following lines when in production mode  
  7. defined('YII_DEBUG'or define('YII_DEBUG',true);  
  8. // specify how many levels of call stack should be shown in each log message  
  9. defined('YII_TRACE_LEVEL'or define('YII_TRACE_LEVEL',3);  
  10.   
  11. require_once($yii);  
  12. Yii::createWebApplication($config)->run();  

头部定义:

      包含全局yii.php和配置文件

$yii = C:\xampp\htdocs\firstone/framework/yii.php

        $config = C:\xampp\htdocs\firstone/protected/config/main.php

      定义调试标机YII_Debug,和YII_TRACE_LEVEL

一.引用$yii指向文件

以下是yii.php源代码:

  1. <?php  
  2. require(dirname(__FILE__).'/YiiBase.php');  
  3. class Yii extends YiiBase  
  4. {  
  5. }  

Yii.php主要有两个功能:第一,引入YiiBase.php ; 第二,定义YiiBase子类Yii

下面是YiiBase.php源代码:

  1. <?php  
  2. defined('YII_BEGIN_TIME'or define('YII_BEGIN_TIME',microtime(true));  
  3. defined('YII_DEBUG'or define('YII_DEBUG',false);  
  4. defined('YII_TRACE_LEVEL'or define('YII_TRACE_LEVEL',0);  
  5. defined('YII_ENABLE_EXCEPTION_HANDLER'or define('YII_ENABLE_EXCEPTION_HANDLER',true);  
  6. defined('YII_ENABLE_ERROR_HANDLER'or define('YII_ENABLE_ERROR_HANDLER',true);  
  7. defined('YII_PATH'or define('YII_PATH',dirname(__FILE__));  
  8. defined('YII_ZII_PATH'or define('YII_ZII_PATH',YII_PATH.DIRECTORY_SEPARATOR.'zii');  
  9.   
  10. /*这个类中方法具体实现太长,我删除掉了。具体的细节后面文章中再分析*/  
  11. class YiiBase  
  12. {  
  13.     public static $classMap=array();  
  14.     public static $enableIncludePath=true;  
  15.   
  16.     private static $_aliases=array('system'=>YII_PATH,'zii'=>YII_ZII_PATH); // alias => path  
  17.     private static $_imports=array();                   // alias => class name or directory  
  18.     private static $_includePaths;                      // list of include paths  
  19.     private static $_app;  
  20.     private static $_logger;  
  21.   
  22.   
  23.     public static function getVersion()  
  24.     public static function createWebApplication($config=null)  
  25.     public static function createConsoleApplication($config=null)  
  26.     public static function createApplication($class,$config=null)  
  27.     public static function app()  
  28.     public static function setApplication($app)  
  29.     public static function getFrameworkPath()  
  30.     public static function createComponent($config)  
  31.     public static function import($alias,$forceInclude=false)  
  32.     public static function getPathOfAlias($alias)  
  33.     public static function setPathOfAlias($alias,$path)  
  34.     public static function autoload($className)  
  35.     public static function trace($msg,$category='application')  
  36.     public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')  
  37.     public static function beginProfile($token,$category='application')  
  38.     public static function endProfile($token,$category='application')  
  39.     public static function getLogger()  
  40.     public static function setLogger($logger)  
  41.     public static function powered()  
  42.     public static function t($category,$message,$params=array(),$source=null,$language=null)  
  43.     public static function registerAutoloader($callback$append=false)  
  44.     private static $_coreClasses=array(  
  45.         'CApplication' => '/base/CApplication.php',  
  46.                 ...........................  
  47.     );  
  48. }  
  49.   
  50. spl_autoload_register(array('YiiBase','autoload'));  
  51. require(YII_PATH.'/base/interfaces.php');  
YiiBase.php中定义了YiiBase类,重要的是执行了spl_autoload_register来实现注册全局类自动加载函数。在此之后,所有php没有包含的类,都会通过YiiBase::autoload方法来加载。

接着引入了interface.php,这个文件给出了yii框架中的接口定义



二.执行Yii类的createWebApplication方法

此方法在它的父类YiiBase中实现,这个类在之前已经完成加载。

  1. public static function createWebApplication($config=null)  
  2. {  
  3.     return self::createApplication('CWebApplication',$config);  
  4. }  
  5. public static function createApplication($class,$config=null)  
  6. {  
  7.     return new $class($config);  
  8. }  

这里创建了CWebApplicaiton对象,参数为全局配置数组$config。

因为是动态创建这里其实只是执行了CWebApplicaiton类的构造函数。而这个类本身没有提供构造函数,而是使用它父类CApplication的构造函数。

顺道说一下,这个时候前面注册的全局自动加载函数就发挥作用了,CWebApplication类就是通过这种方式加载的。


  1. public function __construct($config=null)  
  2. {  
  3.     Yii::setApplication($this); //这只为当前全局实例,单例模式  
  4.   
  5.     // set basePath at early as possible to avoid trouble  
  6.     if(is_string($config))  
  7.         $config=require($config);  
  8.     if(isset($config['basePath']))  
  9.     {  
  10.         $this->setBasePath($config['basePath']);  
  11.         unset($config['basePath']);  
  12.     }  
  13.     else  
  14.         $this->setBasePath('protected');  
  15.     Yii::setPathOfAlias('application',$this->getBasePath());  
  16.     Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));  
  17.     Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');  
  18.   
  19.     $this->preinit();//此函数在CModule中实现为空  
  20.   
  21.     $this->initSystemHandlers(); //异常处理  
  22.     $this->registerCoreComponents();//注册全局核心组件  
  23.   
  24.     $this->configure($config);//配置信息  
  25.     $this->attachBehaviors($this->behaviors);//行为绑定  
  26.     $this->preloadComponents();//预加载组件  
  27.   
  28.     $this->init();  
  29. }  

此段代码运行完,全局CWebApplication对象就创建完成了。


对这段代码分析发现,有以下几个问题值得关注:

1.全局自动加载函数

2.全局异常处理

3.全局核心组件注册

4.配置信息

5.行为绑定

6.组件预加载


后面挨个分析吧


---------------------------------------------------------------------------------------------------------


补充(有几个函数还是值得说一下的):

1.CApplication::setBasePath($path) 

  1. /** 
  2.  * Sets the root directory of the application. 
  3.  * This method can only be invoked at the begin of the constructor. 
  4.  * @param string $path the root directory of the application. 
  5.  * @throws CException if the directory does not exist. 
  6.  */  
  7. public function setBasePath($path)  
  8. {  
  9.     if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))  
  10.         throw new CException(Yii::t('yii','Application base path "{path}" is not a valid directory.',  
  11.             array('{path}'=>$path)));  
  12. }  

realpath函数用来去当前路径的上层目录

C:\xampp\htdocs\firstone\protected\config\..被转化为: C:\xampp\htdocs\firstone\protected

这个函数把CApplication类的_basePath属性设置为指定目录

默认的$_basePath指向protected目录



2.Yii::setPathOfAlias($alias, $path)

  1. public static function setPathOfAlias($alias,$path)  
  2. {  
  3.     if(empty($path))  
  4.         unset(self::$_aliases[$alias]);  
  5.     else  
  6.         self::$_aliases[$alias]=rtrim($path,'\\/');  
  7. }  
Yii类有一个成员变量叫做$_aliases,是一个hash table,里面以key-value形式存储着alias和path。

此函数负责吧有效的alias和path添加到$_aliases

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页