2022年Yii_PHP_框架分析 .pdf
《2022年Yii_PHP_框架分析 .pdf》由会员分享,可在线阅读,更多相关《2022年Yii_PHP_框架分析 .pdf(32页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第 1 页 共 32 页Yii PHP 框架分析Yii PHP 框架分析作者: jjjj http:/ 基于 yii1.0.8 的代码分析的。用了一个下午整理的,流水账,感兴趣的凑合着先看,国庆期间推出个整理修改版,然后再完成后两个部分(MVC 和 Yii 的整体结构分析) 。1. 启动网站的唯一入口程序index.php : $yii=dirname(_FILE_)././framework/yii.php; $config=dirname(_FILE_)./protected/config/main.php; / remove the following line when in prod
2、uction mode defined(YII_DEBUG) or define(YII_DEBUG,true); require_once($yii); Yii:createWebApplication($config)-run(); 上面的 require_once($yii) 引用出了后面要用到的全局类Yii , Yii 类是 YiiBase 类的完全继承:class Yii extends YiiBase 系统的全局访问都是通过Yii 类(即 YiiBase 类)来实现的,Yii 类的成员和方法都是static类型。2. 类加载Yii 利用 PHP5 提供的 spl 库来完成类的自动加
3、载。在YiiBase.php 文件结尾处spl_autoload_register(array(YiiBase,autoload); 将 YiiBase 类的静态方法autoload 注册为类加载器。PHP autoload 的简单原理就是执行new 创建对象或通过类名访问静态成员时,系统将类名传递给被注册的类加载器函数,类加载器函数根据类名自行找到对应的类文件并include 。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 32 页 - - - - - - - - -
4、 第 2 页 共 32 页下面是 YiiBase 类的 autoload 方法:public static function autoload($className) / use include so that the error PHP file may appear if(isset(self:$_coreClasses$className) include(YII_PATH.self:$_coreClasses$className); else if(isset(self:$_classes$className) include(self:$_classes$className); el
5、se include($className.php); 可以看到 YiiBase 的静态成员 $_coreClasses 数组里预先存放着Yii 系统自身用到的类对应的文件路径:private static $_coreClasses=array( CApplication = /base/CApplication.php, CBehavior = /base/CBehavior.php, CComponent = /base/CComponent.php, . ) 非 coreClasse 的类注册在YiiBase 的$_classes 数组中:private static $_classe
6、s=array(); 其他的类需要用Yii:import() 讲类路径导入PHP include paths 中,直接include($className.php) 3. CWebApplication 的创建回到前面的程序入口的Yii:createWebApplication($config)-run(); public static function createWebApplication($config=null) return new CWebApplication($config); 现在 autoload 机制开始工作了。当系统执行new CWebApplication() 的时
7、候,会自动include(YII_PATH./base/CApplication.php) 将 main.php 里的配置信息数组$config 传递给CWebApplication 创建出对象,并执行对象的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 32 页 - - - - - - - - - 第 3 页 共 32 页run() 方法启动框架。CWebApplication 类的继承关系CWebApplication - CApplication - CModule
8、 - CComponent $config 先被传递给CApplication 的构造函数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($configbasePath) $this-setBasePath($configbasePath); unset($configbasePath);
9、else $this-setBasePath(protected); Yii:setPathOfAlias(application,$this-getBasePath(); Yii:setPathOfAlias(webroot,dirname($_SERVERSCRIPT_FILENAME); $this-preinit(); $this-initSystemHandlers(); $this-registerCoreComponents(); $this-configure($config); $this-attachBehaviors($this-behaviors); $this-pre
10、loadComponents(); $this-init(); Yii:setApplication($this); 将自身的实例对象赋给Yii的静态成员$_app,以后可以通过Yii:app() 来取得。后面一段是设置CApplication 对象的 _basePath , 指向 proteced 目录。Yii:setPathOfAlias(application,$this-getBasePath(); Yii:setPathOfAlias(webroot,dirname($_SERVERSCRIPT_FILENAME); 名师资料总结 - - -精品资料欢迎下载 - - - - - -
11、- - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 32 页 - - - - - - - - - 第 4 页 共 32 页设置了两个系统路径别名application 和 webroot,后面再import 的时候可以用别名来代替实际的完整路径。别名配置存放在YiiBase 的 $_aliases 数组中。$this-preinit(); 预初始化。 preinit() 是在CModule 类里定义的,没有任何动作。$this-initSystemHandlers() 方法内容:/* * Initializes the class auto
12、loader and error handlers. */ 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(); 设置系统exception_handler 和 error_handler,指向对象自身提供的两个方法。4.
13、 注册核心组件$this-registerCoreComponents(); 代码如下:protected function registerCoreComponents() parent:registerCoreComponents(); $components=array( urlManager=array( class=CUrlManager, ), request=array( class=CHttpRequest, ), session=array( class=CHttpSession, ), assetManager=array( class=CAssetManager, ),
14、名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 32 页 - - - - - - - - - 第 5 页 共 32 页user=array( class=CWebUser, ), themeManager=array( class=CThemeManager, ), authManager=array( class=CPhpAuthManager, ), clientScript=array( class=CClientScript, ), ); $this-setCom
15、ponents($components); 注册了几个系统组件(Components) 。Components 是在 CModule 里定义和管理的,主要包括两个数组private $_components=array(); private $_componentConfig=array(); 每个Component 都是IApplicationComponent接口的实例,Componemt 的实例存放在$_components 数组里,相关的配置信息存放在$_componentConfig数组里。配置信息包括Component 的类名和属性设置。CWebApplication 对象注册了以
16、下几个Component:urlManager, request,session,assetManager,user,themeManager,authManager,clientScript。CWebApplication 的parent 注册了以下几个Component:coreMessages,db,messages,errorHandler,securityManager,statePersister 。Component 在 YiiPHP里是个非常重要的东西,它的特征是可以通过CModule 的 _get() 和 _set() 方法来访问。Component 注册的时候并不会创建对象
17、实例,而是在程序里被第一次访问到的时候,由CModule 来负责(实际上就是Yii:app() )创建。5. 处理$config 配置继续,$this-configure($config); configure() 还是在 CModule 里:public function configure($config) if(is_array($config) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 32 页 - - - - - - - - - 第 6 页 共 32 页
18、foreach($config as $key=$value) $this-$key=$value; 实际上是把 $config 数组里的每一项传给CModule 的 父类 CComponent _set() 方法。public function _set($name,$value) $setter=set.$name; if(method_exists($this,$setter) $this-$setter($value); else if(strncasecmp($name,on,2)=0 & method_exists($this,$name) /duplicating getEven
19、tHandlers() here for performance $name=strtolower($name); if(!isset($this-_e$name) $this-_e$name=new CList; $this-_e$name-add($value); else if(method_exists($this,get.$name) throw new CException(Yii:t(yii,Property class.property is read only., array(class=get_class($this), property=$name); else thro
20、w new CException(Yii:t(yii,Property class.property is not defined., array(class=get_class($this), property=$name); 我们来看看:if(method_exists($this,$setter) 根据这个条件,$config 数组里的basePath, params, modules, import, components 都被传递给相应的setBasePath(), setParams() 等方法里进行处理。6、$config 之 import 其中import 被传递给CModul
21、e 的 setImport:public function setImport($aliases) foreach($aliases as $alias) Yii:import($alias); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 32 页 - - - - - - - - - 第 7 页 共 32 页 Yii:import($alias) 里的处理:public static function import($alias,$forceInclude=false
22、) / 先判断 $alias 是否存在于YiiBase:$_imports 中,已存在的直接return, 避免重复import。if(isset(self:$_imports$alias) / previously imported return self:$_imports$alias; / $alias 类已定义,记入$_imports ,直接返回if(class_exists($alias,false) return self:$_imports$alias=$alias; / 类似urlManager 这样的已定义于$_coreClasses的类,或不含.的直接类名,记入$_impo
23、rts ,直接返回if(isset(self:$_coreClasses$alias) | ($pos=strrpos($alias,.)=false) / a simple class name self:$_imports$alias=$alias; if($forceInclude) if(isset(self:$_coreClasses$alias) / a core class require(YII_PA TH.self:$_coreClasses$alias); else require($alias.php); return $alias; / 产生一个变量$className
24、,为 $alias最后一个 .后面的部分/ 这样的: x.y.ClassNamer / $className 不等于*, 并且ClassNamer 类已定义的,ClassNamer 记入$_imports ,直接返回if($className=(string)substr($alias,$pos+1)!=* & class_exists($className,false) return self:$_imports$alias=$className; / 取得$alias 里真实的路径部分并且路径有效if($path=self:getPathOfAlias($alias)!=false) /
25、$className!=* ,$className 记入$_imports if($className!=*) self:$_imports$alias=$className; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 32 页 - - - - - - - - - 第 8 页 共 32 页if($forceInclude) require($path.php); else self:$_classes$className=$path.php; return $cla
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年Yii_PHP_框架分析 2022 Yii_PHP_ 框架 分析
限制150内