既然说YII框架,就从程序入口开始会说吧。下面是网站唯一入口index.php代码:
- <?php
- // change the following paths if necessary
- $yii=dirname(__FILE__).'/framework/yii.php';
- $config=dirname(__FILE__).'/protected/config/main.php';
- // remove the following lines when in production mode
- defined('YII_DEBUG') or define('YII_DEBUG',true);
- // specify how many levels of call stack should be shown in each log message
- defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
- require_once($yii);
- 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源代码:
- <?php
- require(dirname(__FILE__).'/YiiBase.php');
- class Yii extends YiiBase
- {
- }
Yii.php主要有两个功能:第一,引入YiiBase.php ; 第二,定义YiiBase子类Yii
下面是YiiBase.php源代码:
- <?php
- defined('YII_BEGIN_TIME') or define('YII_BEGIN_TIME',microtime(true));
- defined('YII_DEBUG') or define('YII_DEBUG',false);
- defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',0);
- defined('YII_ENABLE_EXCEPTION_HANDLER') or define('YII_ENABLE_EXCEPTION_HANDLER',true);
- defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER',true);
- defined('YII_PATH') or define('YII_PATH',dirname(__FILE__));
- defined('YII_ZII_PATH') or define('YII_ZII_PATH',YII_PATH.DIRECTORY_SEPARATOR.'zii');
- /*这个类中方法具体实现太长,我删除掉了。具体的细节后面文章中再分析*/
- class YiiBase
- {
- public static $classMap=array();
- public static $enableIncludePath=true;
- private static $_aliases=array('system'=>YII_PATH,'zii'=>YII_ZII_PATH); // alias => path
- private static $_imports=array(); // alias => class name or directory
- private static $_includePaths; // list of include paths
- private static $_app;
- private static $_logger;
- public static function getVersion()
- public static function createWebApplication($config=null)
- public static function createConsoleApplication($config=null)
- public static function createApplication($class,$config=null)
- public static function app()
- public static function setApplication($app)
- public static function getFrameworkPath()
- public static function createComponent($config)
- public static function import($alias,$forceInclude=false)
- public static function getPathOfAlias($alias)
- public static function setPathOfAlias($alias,$path)
- public static function autoload($className)
- public static function trace($msg,$category='application')
- public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')
- public static function beginProfile($token,$category='application')
- public static function endProfile($token,$category='application')
- public static function getLogger()
- public static function setLogger($logger)
- public static function powered()
- public static function t($category,$message,$params=array(),$source=null,$language=null)
- public static function registerAutoloader($callback, $append=false)
- private static $_coreClasses=array(
- 'CApplication' => '/base/CApplication.php',
- ...........................
- );
- }
- spl_autoload_register(array('YiiBase','autoload'));
- require(YII_PATH.'/base/interfaces.php');
接着引入了interface.php,这个文件给出了yii框架中的接口定义
二.执行Yii类的createWebApplication方法
此方法在它的父类YiiBase中实现,这个类在之前已经完成加载。
- public static function createWebApplication($config=null)
- {
- return self::createApplication('CWebApplication',$config);
- }
- public static function createApplication($class,$config=null)
- {
- return new $class($config);
- }
这里创建了CWebApplicaiton对象,参数为全局配置数组$config。
因为是动态创建这里其实只是执行了CWebApplicaiton类的构造函数。而这个类本身没有提供构造函数,而是使用它父类CApplication的构造函数。
顺道说一下,这个时候前面注册的全局自动加载函数就发挥作用了,CWebApplication类就是通过这种方式加载的。
- 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']));
- Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');
- $this->preinit();//此函数在CModule中实现为空
- $this->initSystemHandlers(); //异常处理
- $this->registerCoreComponents();//注册全局核心组件
- $this->configure($config);//配置信息
- $this->attachBehaviors($this->behaviors);//行为绑定
- $this->preloadComponents();//预加载组件
- $this->init();
- }
此段代码运行完,全局CWebApplication对象就创建完成了。
对这段代码分析发现,有以下几个问题值得关注:
1.全局自动加载函数
2.全局异常处理
3.全局核心组件注册
4.配置信息
5.行为绑定
6.组件预加载
后面挨个分析吧
---------------------------------------------------------------------------------------------------------
补充(有几个函数还是值得说一下的):
1.CApplication::setBasePath($path)
- /**
- * Sets the root directory of the application.
- * This method can only be invoked at the begin of the constructor.
- * @param string $path the root directory of the application.
- * @throws CException if the directory does not exist.
- */
- 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)));
- }
realpath函数用来去当前路径的上层目录
C:\xampp\htdocs\firstone\protected\config\..被转化为: C:\xampp\htdocs\firstone\protected
这个函数把CApplication类的_basePath属性设置为指定目录
默认的$_basePath指向protected目录
2.Yii::setPathOfAlias($alias, $path)
- public static function setPathOfAlias($alias,$path)
- {
- if(empty($path))
- unset(self::$_aliases[$alias]);
- else
- self::$_aliases[$alias]=rtrim($path,'\\/');
- }
此函数负责吧有效的alias和path添加到$_aliases