【Yii】模块module

来源:互联网 发布:台湾uu聊天室软件 编辑:程序博客网 时间:2024/05/17 22:49

module是对相同业务逻辑的app中的内容模块化,比如博客前台系统可以模块化成blog,博客后台系统可以模块化成admin,模块化便于对应用的管理扩展。

加载module的配置

[php] view plaincopy
  1. //加载框架中自带gii模块和一个自定义admin模块  
  2. 'modules'=>array(  
  3.     // uncomment the following to enable the Gii tool  
  4.   
  5.     'gii'=>array(  
  6.         'class'=>'system.gii.GiiModule',  
  7.         'password'=>'111111',  
  8.         // If removed, Gii defaults to localhost only. Edit carefully to taste.  
  9.         'ipFilters'=>array('127.0.0.1','::1'),  
  10.     ),  
  11.     'admin'   
  12.       
  13. ),  
[php] view plaincopy
  1. //应用初始化配置时通过CModule::setModules()来配置模块  
  2. public function setModules($modules)  
  3. {  
  4.     foreach($modules as $id=>$module)  
  5.     {  
  6.         if(is_int($id))  
  7.         {  
  8.             $id=$module;  
  9.             $module=array();  
  10.         }  
  11.         if(!isset($module['class']))  
  12.         {  
  13.             Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id);  
  14.             $module['class']=$id.'.'.ucfirst($id).'Module';  
  15.         }  
  16.   
  17.         if(isset($this->_moduleConfig[$id]))  
  18.             $this->_moduleConfig[$id]=CMap::mergeArray($this->_moduleConfig[$id],$module);  
  19.         else  
  20.             $this->_moduleConfig[$id]=$module;  
  21.     }  
  22. }  
定位模块
由module[/controller/action]获取路由中第一个"/"前字符串(必须是只含字母,否则抛出404错误)假定是模块id,根据模块id判断如果存在该id的模块或者存在该id的模块配置,则返回模块,由代码分析可以知道如果禁用一个模块很简单,只需在主配置文件中加上'enabled' => false就可。

[php] view plaincopy
  1. CWebApplication:  
  2. //路由分发,定位模块和模块下的controller  
  3. public function createController($route,$owner=null)  
  4. {  
  5.      
  6.     if($owner===null)  
  7.         $owner=$this;  
  8.     if(($route=trim($route,'/'))==='')  
  9.         $route=$owner->defaultController;  
  10.     $caseSensitive=$this->getUrlManager()->caseSensitive;  
  11.   
  12.     $route.='/';  
  13.     while(($pos=strpos($route,'/'))!==false)  
  14.     {  
  15.         $id=substr($route,0,$pos);  
  16.         if(!preg_match('/^\w+$/',$id))  
  17.             return null;  
  18.         if(!$caseSensitive)  
  19.             $id=strtolower($id);  
  20.         $route=(string)substr($route,$pos+1);  
  21.         if(!isset($basePath))  // first segment  
  22.         {  
  23.             if(isset($owner->controllerMap[$id]))  
  24.             {  
  25.                 return array(  
  26.                     Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner),  
  27.                     $this->parseActionParams($route),  
  28.                 );  
  29.             }  
  30.              
  31.             if(($module=$owner->getModule($id))!==null)  
  32.                 /* 
  33.                     如果找到module,再次调用本方法, 
  34.                     注意这个时候的第二个参数ower不再是CWebApplication或其子类,而是CWebModule子类 
  35.                     这对获取控制器和视图的默认路径很重要,CWebModule控制器路径是相应module下面的 
  36.                 */  
  37.                 return $this->createController($route,$module);   
  38.   
  39.             $basePath=$owner->getControllerPath();  
  40.             $controllerID='';  
  41.         }  
  42.         else  
  43.             $controllerID.='/';  
  44.         $className=ucfirst($id).'Controller';  
  45.         $classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php';  
  46.         if(is_file($classFile))  
  47.         {  
  48.             if(!class_exists($className,false))  
  49.                 require($classFile);  
  50.             if(class_exists($className,false) && is_subclass_of($className,'CController'))  
  51.             {  
  52.                 $id[0]=strtolower($id[0]);  
  53.                 return array(  
  54.                     new $className($controllerID.$id,$owner===$this?null:$owner),  
  55.                     $this->parseActionParams($route),  
  56.                 );  
  57.             }  
  58.             return null;  
  59.         }  
  60.         $controllerID.=$id;  
  61.         $basePath.=DIRECTORY_SEPARATOR.$id;  
  62.     }  
  63. }  
[php] view plaincopy
  1. CWebModule:  
  2. /** 
  3.  * Retrieves the named application module. 查找模块 
  4.  * The module has to be declared in {@link modules}. A new instance will be created 
  5.  * when calling this method with the given ID for the first time. 
  6.  * @param string $id application module ID (case-sensitive) 
  7.  * @return CModule the module instance, null if the module is disabled or does not exist. 
  8.  */  
  9. public function getModule($id)  
  10. {  
  11.     if(isset($this->_modules[$id]) || array_key_exists($id,$this->_modules))  
  12.         return $this->_modules[$id];  
  13.     else if(isset($this->_moduleConfig[$id]))  
  14.     {  
  15.         $config=$this->_moduleConfig[$id];  
  16.         if(!isset($config['enabled']) || $config['enabled'])  
  17.         {  
  18.              
  19.             Yii::trace("Loading \"$id\" module",'system.base.CModule');  
  20.             $class=$config['class'];  
  21.          
  22.             unset($config['class'], $config['enabled']);  
  23.             if($this===Yii::app())  
  24.                 $module=Yii::createComponent($class,$id,null,$config);  
  25.             else  
  26.                 $module=Yii::createComponent($class,$this->getId().'/'.$id,$this,$config);  
  27.             return $this->_modules[$id]=$module;  
  28.         }  
  29.     }  
  30. }  
模块里有一个CWebModule的子类重载CWebModule的一些方法,通过int()导入模块中要导入的路径,通过 beforeControllerAction($controller, $action)和afterControllerAction($controller, $action)实现动作执行前后钩子的添加。
[php] view plaincopy
  1. class AdminModule extends CWebModule  
  2. {  
  3.     public function init()  
  4.     {  
  5.         // this method is called when the module is being created  
  6.         // you may place code here to customize the module or the application  
  7.   
  8.         // import the module-level models and components  
  9.         $this->setImport(array(  
  10.             'admin.models.*',  
  11.             'admin.components.*',  
  12.         ));  
  13.     }  
  14.   
  15.     public function beforeControllerAction($controller$action)  
  16.     {  
  17.         if(parent::beforeControllerAction($controller$action))  
  18.         {  
  19.             // this method is called before any module controller action is performed  
  20.             // you may place customized code here  
  21.             return true;  
  22.         }  
  23.         else  
  24.             return false;  
  25.     }  
  26. }  

0 0