[Yii2笔记]039模块(Modules) [ 技术分享 ]
说明
学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!
原文网址:
http://www.yiiframework.com/doc-2.0/guide-structure-modules.html
本文主题:模块(Modules)
模块(Module)是自包含的软件单元,它包含模型、视图、控制器和其他支持组件。模块在应用中安装后,用户就可以访问模块的控制器了。因为这些原因,模块经常被看成是最小应用。模块与应用不同之处在于:模块不能被独立部署,且必须存在于应用之中。
1、Creating Modules(创建模块)
一个模块被组织在模块的基本目录(base path)之下,在基本目录中有子目录,如controllers、models、views,其中存放了控制器、模型、视图和其他代码,这与应用有些相似。以下示例展示了一个模块中的内容:
forum/
Module.php 模块类文件
controllers/ 包含控制器类文件
DefaultController.php 默认控制器类文件
models/ 包含模型类文件
views/ 包含控制器视图和模板文件
layouts/ 包含模板文件
default/ 包含DefaultController控制器的视图文件
index.php index视图文件
Module Classes(模块类)
每个模块将包括一个唯一的模块类,此类继承自yii\base\Module,此类应位于模块基础目录下,并是可以自动加载的。当一个模块被访问时,对应模块类的单一实例将被创建。与应用实例一样,模块实例被用于模块代码间共享数据和组件。
下面是一个模块类的例子:
namespace app\modules\forum;
class Module extends \yii\base\Module{
public function init(){
parent::init();
$this->params['foo']='bar';
}
}
如果init()方法包含大量初始化模块属性的代码 ,你可以将它们保存为配置文件,然后在init()方法中加载它:
public function init(){
parent::init();
//加载config.php初始化模块配置
\Yii::configure($this,require(__DIR__.'/config.php'));
}
config.php可以包含以下内容,与应用配置相类似:
<?php
return [
'component' =>[
//组件配置列表
],
'params'=>[
//参数列表
]
];
Controllers in Modules(模块中的控制器)
在模块中创建控制器,一个惯例是将控制器类放在模块类命名空间的子空间controllers下。也就是说控制器类文件将被放在模块基础目录的controllers目录下。例如,要在forum模块下创建一个post控制器,你需要声明控制器类,代码如下:
namespace app\modules\forum\controllers;
use yii\web\Controller;
class PostController extends Controller{
}
你可以设置yii\base\Module::$controllerNamespace 属性来自定义控制器类的命名空间。如果有一些控制器不在此命名空间下,你可以通过配置yii\base\Module::$controllerMap 属性来使它们可以被获取到,与应用中作法相类似。
Views in Modules(模块的视图)
模块中的视图将被放置在模块基础目录的views目录下,为了模块中控制器渲染,这些视图放在目录views/ControllerID目录下,ControllerID是指控制器的ID,例如,如果控制器类是PostController,视图目录就是模块基础目录下的views/post目录。 一个模块能定义一个模板(layout),此模板可以被模块控制器渲染的视图所应用。模板默认被放置在views/layouts目录下,你可以配置yii\base\Module::$layout 属性来指定模板名称,如果你没有配置layout属性,将使用应用模板。
Console commands in Modules
你的模块可以声明命令,它将在控制台模式(Console mode)中被使用。
当Yii以控制台模式被执行时,要让命令行能够看到你的命令,需要修改yii\base\Module::$controllerNamespace 属性,然后将它指向命令的命名空间。
要实现此目标的一个方法是在模块的init()方法中检测Yii应用的实例类型:
public function init(){
parent::init();
if(Yii::$app instanceof \yii\console\Application){
$this->controllerNamespace='app\modules\forum\commands';
}
}
在命令行中使用如下路由格式,你的命令将是有效的: yii //
2、Using Modules(使用模块)
应用中要使用一个模块,只需在应用配置的modules属性中简单设置应用列表即可。要使用forum模块,应用配置如下:
[
'modules'=>[
'forum' =>[
'class'=>'app\modules\forum\Module',
],
],
]
modules属性使用一个模块配置数组,每个数组键表示模块ID,此ID在应用中是唯一,以区别与其他模块,对应的数组值是创建模块的配置。
Routes(路由)
与在应用中访问控制器相类似,路由也被用于在模块中定义控制器。一个模块中的路由必须以模块ID开始,其后是控制器ID和动作ID。例如,一个应用使用了一个名为forum的模块,路由forum/post/index将表示模块中的post控制器的index动作。如果路由只包含模块ID,将由yii\base\Module::$defaultRoute 属性来决定哪个控制器/动作将被使用,默认值是default,也就是说路由forum代表forum模块中的default控制器。
Accessing Modules(获取模块)
在一个模块中,你可能会需要获取模块类的实例,这样你能找到模块ID,模块参数,模块组件等等,使用如下代码即可:
$module=MyModuleClass::getInstance();
MyModuleClass是指你想要的模块类名称。getInstance()方法将返回当前请求的模块类的实例。如果模块没有查找到,此方法将返回null,获取模块forum:
$module=\app\modules\forum\Module::getInstance();
注意你不能手动创建一个模块的新实例,因为它与Yii为响应请求而创建的模块实例是不相同的。 信息:当开发一个模块时,你不能假设模块使用固定的ID,这是因为在应用或其他模块中一个模块可以与任意的ID相关联。要获取模块ID,应当使用上面的方法先获取模块实例,然后再通过$module->id来得到ID。
modules
你也可以使用以下方法获取模块的实例:
//获取ID为forum的模块
$module=\Yii::$app->getModule('forum');
//获取当前请求控制器所属的模块
$module=\Yii::$app->controller->module;
当你知道模块ID时常用第一种方法,当你仅知道请求的控制器时最好使用第二种方法。 当你获取到模块实例时,你可以获取参数和模块注册的组件,例如:
$maxPostCount=$module->params['maxPostCount'];
Bootstrapping Modules(引导模块)
一些模块可能会在每个请求时都被运行,debug模块就是个例子。要做到这些,在应用配置的bootstrap属性中列出这些模块的ID即可。 例如,以下应用配置确保debug模块一直被加载:
[
'bootstarp' =>[
'debug',
],
'modules'=>[
'debug' =>'yii\debug\Module',
]
]
3、Nested Modules(嵌套模块)
模块可以无限级的嵌套,也就是说一个模块可以包含其他模块,其他模块可以再包含模块。我们称前者为父模块,后者为子模块,子模块必须在它们的父模块的modules属性中声明,例如:
namespace app\modules\forum;
class Module extends \yii\base\Moduel{
public function init(){
parent::init();
$this->modules=[
'admin' =>[
'class'=>'app\modules\forum\modules\admin\Module',
],
];
}
}
对于嵌套模块中的控制器,它的路由将包含所有祖先模块的ID,例如,forum/admin/dashboard/index表示admin模块dashboard控制器的index动作,admin模块是forum模块的子模块。 信息:getModule方法仅返回直接子模块。yii\base\Application::$loadedModules 属性保存了已加载模块的列表,包括直接子模块和嵌套模块,按照它们的类名称进行索引。
4、Best Practices(最佳实践)
模块常用于大型应用,它的功能被划分为多个组,每组由一系列联系紧密的功能组成。每个功能组可以作为一个模块进行开发,这样模块的开发和维护可以由一个开发人员或团队负责。 在功能组级别,模块也是一个很好的代码复用方法。一些常用的功能,例如用户管理,评论管理,可以以模块的形式来开发,这样在以后的项目中它们可以被轻松复用。
(全文完)
共 0 条回复
阿江
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276