模塊(Modules)

2018-02-24 15:40 更新

模塊

模塊是獨立的軟件單元,由模型,?視圖,?控制器和其他支持組件組成, 終端用戶可以訪問在應用主體中已安裝的模塊的控制器, 模塊被當成小應用主體來看待,和應用主體不同的是, 模塊不能單獨部署,必須屬于某個應用主體。

創(chuàng)建模塊

模塊被組織成一個稱為yii\base\Module::basePath的目錄, 在該目錄中有子目錄如controllers,?models,?views?分別為對應控制器,模型,視圖和其他代碼,和應用非常類似。 如下例子顯示一個模型的目錄結(jié)構(gòu):

forum/
    Module.php                   模塊類文件
    controllers/                 包含控制器類文件
        DefaultController.php    default 控制器類文件
    models/                      包含模型類文件
    views/                       包含控制器視圖文件和布局文件
        layouts/                 包含布局文件
        default/                 包含DefaultController控制器視圖文件
            index.php            index視圖文件

模塊類

每個模塊都有一個繼承yii\base\Module的模塊類,該類文件直接放在模塊的yii\base\Module::basePath目錄下, 并且能被?自動加載。當一個模塊被訪問,和?應用主體實例?類似會創(chuàng)建該模塊類唯一實例,模塊實例用來幫模塊內(nèi)代碼共享數(shù)據(jù)和組件。

以下示例一個模塊類大致定義:

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配置文件可能包含以下內(nèi)容,類似應用主體配置.

<?php
return [
    'components' => [
        // list of component configurations
    ],
    'params' => [
        // list of parameters
    ],
];

模塊中的控制器

創(chuàng)建模塊的控制器時,慣例是將控制器類放在模塊類命名空間的controllers子命名空間中, 也意味著要將控制器類文件放在模塊yii\base\Module::basePath目錄中的controllers子目錄中。 例如,上小節(jié)中要在forum模塊中創(chuàng)建post控制器,應像如下申明控制器類:

namespace app\modules\forum\controllers;

use yii\web\Controller;

class PostController extends Controller
{
    // ...
}

可配置yii\base\Module::controllerNamespace屬性來自定義控制器類的命名空間, 如果一些控制器不再該命名空間下,可配置yii\base\Module::controllerMap屬性讓它們能被訪問, 這類似于?應用主體配置?所做的。

模塊中的視圖

視圖應放在模塊的yii\base\Module::basePath對應目錄下的?views?目錄, 對于模塊中控制器對應的視圖文件應放在views/ControllerID?目錄下, 其中ControllerID對應?控制器 ID. For example, if 例如,假定控制器類為PostController,目錄對應模塊yii\base\Module::basePath目錄下的?views/post?目錄。

模塊可指定?布局,它用在模塊的控制器視圖渲染。 布局文件默認放在?views/layouts?目錄下,可配置yii\base\Module::layout屬性指定布局名, 如果沒有配置?layout?屬性名,默認會使用應用的布局。

使用模塊

要在應用中使用模塊,只需要將模塊加入到應用主體配置的yii\base\Application::modules屬性的列表中, 如下代碼的應用主體配置?使用?forum?模塊:

[
    'modules' => [
        'forum' => [
            'class' => 'app\modules\forum\Module',
            // ... 模塊其他配置 ...
        ],
    ],
]

yii\base\Application::modules 屬性使用模塊配置數(shù)組,每個數(shù)組鍵為模塊 ID, 它標識該應用中唯一的模塊,數(shù)組的值為用來創(chuàng)建模塊的?配置。

路由

和訪問應用的控制器類似,路由?也用在模塊中控制器的尋址, 模塊中控制器的路由必須以模塊ID開始,接下來為控制器ID和操作ID。 例如,假定應用使用一個名為?forum?模塊,路由forum/post/index?代表模塊中?post?控制器的?index?操作, 如果路由只包含模塊ID,默認為?default?的yii\base\Module::defaultRoute 屬性來決定使用哪個控制器/操作, 也就是說路由?forum?可能代表?forum模塊的?default?控制器。

訪問模塊

在模塊中,可能經(jīng)常需要獲取模塊類的實例來訪問模塊ID,模塊參數(shù),模塊組件等, 可以使用如下語句來獲?。?/p>

$module = MyModuleClass::getInstance();

其中?MyModuleClass?對應你想要的模塊類,getInstance()?方法返回當前請求的模塊類實例, 如果模塊沒有被請求,該方法會返回空,注意不需要手動創(chuàng)建一個模塊類,因為手動創(chuàng)建的和Yii處理請求時自動創(chuàng)建的不同。

補充: 當開發(fā)模塊時,你不能假定模塊使用固定的ID,因為在應用或其他沒模塊中,模塊可能會對應到任意的ID, 為了獲取模塊ID,應使用上述代碼獲取模塊實例,然后通過$module->id獲取模塊ID。

也可以使用如下方式訪問模塊實例:

// 獲取ID為 "forum" 的模塊
$module = \Yii::$app->getModule('forum');

// 獲取處理當前請求控制器所屬的模塊
$module = \Yii::$app->controller->module;

第一種方式僅在你知道模塊ID的情況下有效,第二種方式在你知道處理請求的控制器下使用。

一旦獲取到模塊實例,可訪問注冊到模塊的參數(shù)和組件,例如:

$maxPostCount = $module->params['maxPostCount'];

引導啟動模塊

有些模塊在每個請求下都有運行, yii\debug\Module 模塊就是這種, 為此將這種模塊加入到應用主體的 yii\base\Application::bootstrap 屬性中。

例如,如下示例的應用主體配置會確保debug模塊每次都被加載:

[
    'bootstrap' => [
        'debug',
    ],

    'modules' => [
        'debug' => 'yii\debug\Module',
    ],
]

模塊嵌套

模塊可無限級嵌套,也就是說,模塊可以包含另一個包含模塊的模塊,我們稱前者為父模塊,后者為子模塊, 子模塊必須在父模塊的yii\base\Module::modules屬性中申明,例如:

namespace app\modules\forum;

class Module extends \yii\base\Module
{
    public function init()
    {
        parent::init();

        $this->modules = [
            'admin' => [
                // 此處應考慮使用一個更短的命名空間
                'class' => 'app\modules\forum\modules\admin\Module',
            ],
        ];
    }
}

在嵌套模塊中的控制器,它的路由應包含它所有祖先模塊的ID,例如forum/admin/dashboard/index?代表 在模塊forum中子模塊admindashboard控制器的index操作。

最佳實踐

模塊在大型項目中常備使用,這些項目的特性可分組,每個組包含一些強相關(guān)的特性, 每個特性組可以做成一個模塊由特定的開發(fā)人員和開發(fā)組來開發(fā)和維護。

在特性組上,使用模塊也是重用代碼的好方式,一些常用特性,如用戶管理,評論管理,可以開發(fā)成模塊, 這樣在相關(guān)項目中非常容易被重用。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號