模块结构
在YII中,程序入口是一个继承Capplication的CWebApplication的应用程序,在一个web请求的整个过程中,控制器,模型和视图都是由Application进行创建和控制。首先我们来看一下CWebApplication的类的继承结构:从上面我们可以看到CWebApplication本身也是一个CModue。在YII中,模块之间是一个树形结构。即每一个模块都可以包含多个子模块,每一个子模块可以继续包含子模块.其中APP为树的头节点,如图:对于一个具体请求,假设route=A/B/C/D,下面我们讲述一下,APP怎么选择相应的模块和模块中的控制器Controller和动作Action。具体的流程图如下:对于读过YII源码都直到,任何一个web请求都是通过CApplication::Run()函数开始,进入到CWebApplication::PRocessRequest()。源码分别如下:程序真正的进行到相应模块,控制器,动作是在函数processRequest的$this->runController($route);中,该函数传入的参数为$route。何为 $route。其实$route是一个类似A/B/C/D格式的字符串,该字符串中可能包含了模块,控制器,动作和$_GET相关参数。该函数是也是定义在CWebApplication中。代码如下:通过该函数的名称字面意思为"运行控制器"。因此首先第一步就是要创建一个控制器,即函数createController($route)。我们知道控制器的是包含在模块中,因此也在该函数中,通过分析$route可以得到相应的模块,以及模块中的控制器和相应的动作,即list($controller,$actionID)=$ca;上面的流程图即为该函数createController($route)的函数流程图。现在应该清楚了一个模块是怎么被web用户所调用了吧。下面我们说一下程序怎么在应用程序中添加模块,当然可能是通过配置文件。
添加模块
模块源码分析
public function __construct($id,$parent,$config=null)//$id为模块ID,$parent为父模块ID { $this->_id=$id; $this->_parentModule=$parent; // 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']); } Yii::setPathOfAlias($id,$this->getBasePath());//把该模块的路径添加到Alias中,方便访问 //下面几个函数就是模块的初始化需要做的几件事情,可以通过重写preinit()和init()来自定义模块可以通过自定义相应的函数来定制和初始化模块的参数 $this->preinit();//预初始化,一般用来设置模块相关的行为对象$behaviors[],预加载对象$preload[],和其他配置。 $this->configure($config);//加载配置 $this->attachBehaviors($this->behaviors);//挂载行为对象 $this->preloadComponents();//加载CModule::$preload[]中的预加载组件 $this->init();//模块真正初始化,一般情况下,重写该函数完整模块初始化 }CWebModule分析
public function beforeControllerAction($controller,$action) { if(($parent=$this->getParentModule())===null) $parent=Yii::app(); return $parent->beforeControllerAction($controller,$action); } public function afterControllerAction($controller,$action) { if(($parent=$this->getParentModule())===null) $parent=Yii::app(); $parent->afterControllerAction($controller,$action); } 可以通过此两个函数对该模块中的每一个请求进行一些改写,控制以及收尾的相关工作。在自定义的模块中,两个函数的覆盖的模版如下:public function beforeControllerAction($controller, $action) { if(parent::beforeControllerAction($controller, $action)) { // this method is called before any module controller action is performed // you may place customized code here return true; } else return false; }array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',//模块的路径 'preload'=>array('log'),//需要预先加载日志组件 'import'=>array('application.models.*', 'application.components.*',),//需要include的路径 //组件的配置 'components'=>array( 'user'=>array(//用户组件的配置 'allowAutoLogin'=>true ), 'log'=>array(//日志组件的配置 'class'=>'CLogRouter', 'routes'=>array(array('class'=>'CWebLogRoute','levels'=>'trace, profile')) ) ), //模块的配置 'modules'=>array( 'gii'=>array(//自动生成代码模块的配置 'class'=>'system.gii.GiiModule', 'passWord'=>'123456' ), ),);
http://blog.csdn.net/colzer/article/details/8443042
新闻热点
疑难解答