您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > Yii PHP 框架分析
第1页共32页YiiPHP框架分析YiiPHP框架分析(一)作者:wdy基于yii1.0.8的代码分析的。用了一个下午整理的,流水账,感兴趣的凑合着先看,国庆期间推出个整理修改版,然后再完成后两个部分(MVC和Yii的整体结构分析)。1.启动网站的唯一入口程序index.php:$yii=dirname(__FILE__).'/../framework/yii.php';$config=dirname(__FILE__).'/protected/config/main.php';//removethefollowinglinewheninproductionmodedefined('YII_DEBUG')ordefine('YII_DEBUG',true);require_once($yii);Yii::createWebApplication($config)-run();上面的require_once($yii)引用出了后面要用到的全局类Yii,Yii类是YiiBase类的完全继承:classYiiextendsYiiBase{}系统的全局访问都是通过Yii类(即YiiBase类)来实现的,Yii类的成员和方法都是static类型。2.类加载Yii利用PHP5提供的spl库来完成类的自动加载。在YiiBase.php文件结尾处spl_autoload_register(array('YiiBase','autoload'));将YiiBase类的静态方法autoload注册为类加载器。PHPautoload的简单原理就是执行new创建对象或通过类名访问静态成员时,系统将类名传递给被注册的类加载器函数,类加载器函数根据类名自行找到对应的类文件并include。第2页共32页下面是YiiBase类的autoload方法:publicstaticfunctionautoload($className){//useincludesothattheerrorPHPfilemayappearif(isset(self::$_coreClasses[$className]))include(YII_PATH.self::$_coreClasses[$className]);elseif(isset(self::$_classes[$className]))include(self::$_classes[$className]);elseinclude($className.'.php');}可以看到YiiBase的静态成员$_coreClasses数组里预先存放着Yii系统自身用到的类对应的文件路径:privatestatic$_coreClasses=array('CApplication'='/base/CApplication.php','CBehavior'='/base/CBehavior.php','CComponent'='/base/CComponent.php',...)非coreClasse的类注册在YiiBase的$_classes数组中:privatestatic$_classes=array();其他的类需要用Yii::import()讲类路径导入PHPincludepaths中,直接include($className.'.php')3.CWebApplication的创建回到前面的程序入口的Yii::createWebApplication($config)-run();publicstaticfunctioncreateWebApplication($config=null){returnnewCWebApplication($config);}现在autoload机制开始工作了。当系统执行newCWebApplication()的时候,会自动include(YII_PATH.'/base/CApplication.php')将main.php里的配置信息数组$config传递给CWebApplication创建出对象,并执行对象的第3页共32页run()方法启动框架。CWebApplication类的继承关系CWebApplication-CApplication-CModule-CComponent$config先被传递给CApplication的构造函数publicfunction__construct($config=null){Yii::setApplication($this);//setbasePathatearlyaspossibletoavoidtroubleif(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($this);将自身的实例对象赋给Yii的静态成员$_app,以后可以通过Yii::app()来取得。后面一段是设置CApplication对象的_basePath,指向proteced目录。Yii::setPathOfAlias('application',$this-getBasePath());Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));第4页共32页设置了两个系统路径别名application和webroot,后面再import的时候可以用别名来代替实际的完整路径。别名配置存放在YiiBase的$_aliases数组中。$this-preinit();预初始化。preinit()是在CModule类里定义的,没有任何动作。$this-initSystemHandlers()方法内容:/***Initializestheclassautoloaderanderrorhandlers.*/protectedfunctioninitSystemHandlers(){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.注册核心组件$this-registerCoreComponents();代码如下:protectedfunctionregisterCoreComponents(){parent::registerCoreComponents();$components=array('urlManager'=array('class'='CUrlManager',),'request'=array('class'='CHttpRequest',),'session'=array('class'='CHttpSession',),'assetManager'=array('class'='CAssetManager',),第5页共32页'user'=array('class'='CWebUser',),'themeManager'=array('class'='CThemeManager',),'authManager'=array('class'='CPhpAuthManager',),'clientScript'=array('class'='CClientScript',),);$this-setComponents($components);}注册了几个系统组件(Components)。Components是在CModule里定义和管理的,主要包括两个数组private$_components=array();private$_componentConfig=array();每个Component都是IApplicationComponent接口的实例,Componemt的实例存放在$_components数组里,相关的配置信息存放在$_componentConfig数组里。配置信息包括Component的类名和属性设置。CWebApplication对象注册了以下几个Component:urlManager,request,session,assetManager,user,themeManager,authManager,clientScript。CWebApplication的parent注册了以下几个Component:coreMessages,db,messages,errorHandler,securityManager,statePersister。Component在YiiPHP里是个非常重要的东西,它的特征是可以通过CModule的__get()和__set()方法来访问。Component注册的时候并不会创建对象实例,而是在程序里被第一次访问到的时候,由CModule来负责(实际上就是Yii::app())创建。5.处理$config配置继续,$this-configure($config);configure()还是在CModule里:publicfunctionconfigure($config){if(is_array($config))第6页共32页{foreach($configas$key=$value)$this-$key=$value;}}实际上是把$config数组里的每一项传给CModule的父类CComponent__set()方法。publicfunction__set($name,$value){$setter='set'.$name;if(method_exists($this,$setter))$this-$setter($value);elseif(strncasecmp($name,'on',2)===0&&method_exists($this,$name)){//duplicatinggetEventHandlers()hereforperformance$name=strtolower($name);if(!isset($this-_e[$name]))$this-_e[$name]=newCList;$this-_e[$name]-add($value);}elseif(method_exists($this,'get'.$name))throw
本文标题:Yii PHP 框架分析
链接地址:https://www.777doc.com/doc-5040151 .html