模塊是獨立的軟件單元,由模型, 視圖, 控制器和其他支持組件組成, 終端用戶可以訪問在應用主體中已安裝的模塊的控制器, 模塊被當成小應用主體來看待,和應用主體不同的是, 模塊不能單獨部署,必須屬于某個應用主體。
創建模塊
模塊被組織成一個稱為[[yii\base\Module::basePath|base path]]的目錄, 在該目錄中有子目錄如controllers,models,views分別為對應控制器,模型,視圖和其他代碼,和應用非常類似。 如下例子顯示一個模型的目錄結構:
forum/ Module.php 模塊類文件 controllers/ 包含控制器類文件 DefaultController.php default 控制器類文件 models/ 包含模型類文件 views/ 包含控制器視圖文件和布局文件 layouts/ 包含布局文件 default/ 包含DefaultController控制器視圖文件 index.php index視圖文件
模塊類
每個模塊都有一個繼承[[yii\base\Module]]的模塊類,該類文件直接放在模塊的[[yii\base\Module::basePath|base path]]目錄下, 并且能被 自動加載。當一個模塊被訪問,和 應用主體實例 類似會創建該模塊類唯一實例,模塊實例用來幫模塊內代碼共享數據和組件。
以下示例一個模塊類大致定義:
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 [ 'components' => [ // list of component configurations ], 'params' => [ // list of parameters ], ];
模塊中的控制器
創建模塊的控制器時,慣例是將控制器類放在模塊類命名空間的controllers子命名空間中, 也意味著要將控制器類文件放在模塊[[yii\base\Module::basePath|base path]]目錄中的controllers子目錄中。 例如,上小節中要在forum模塊中創建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|base path]]對應目錄下的views目錄, 對于模塊中控制器對應的視圖文件應放在views/ControllerID目錄下, 其中ControllerID對應 控制器 ID. For example, if 例如,假定控制器類為PostController,目錄對應模塊[[yii\base\Module::basePath|base path]]目錄下的views/post目錄。
模塊可指定 布局,它用在模塊的控制器視圖渲染。 布局文件默認放在views/layouts目錄下,可配置[[yii\base\Module::layout]]屬性指定布局名, 如果沒有配置layout屬性名,默認會使用應用的布局。
使用模塊
要在應用中使用模塊,只需要將模塊加入到應用主體配置的[[yii\base\Application::modules|modules]]屬性的列表中, 如下代碼的應用主體配置 使用forum模塊:
[ 'modules' => [ 'forum' => [ 'class' => 'app\modules\forum\Module', // ... 模塊其他配置 ... ], ], ]
[[yii\base\Application::modules|modules]] 屬性使用模塊配置數組,每個數組鍵為模塊 ID, 它標識該應用中唯一的模塊,數組的值為用來創建模塊的 配置。
和訪問應用的控制器類似,路由 也用在模塊中控制器的尋址, 模塊中控制器的路由必須以模塊ID開始,接下來為控制器ID和操作ID。 例如,假定應用使用一個名為forum模塊,路由forum/post/index代表模塊中post控制器的index操作, 如果路由只包含模塊ID,默認為default的[[yii\base\Module::defaultRoute]] 屬性來決定使用哪個控制器/操作, 也就是說路由forum可能代表forum模塊的default控制器。
訪問模塊
在模塊中,可能經常需要獲取模塊類的實例來訪問模塊ID,模塊參數,模塊組件等, 可以使用如下語句來獲取:
$module = MyModuleClass::getInstance();
其中MyModuleClass對應你想要的模塊類,getInstance()方法返回當前請求的模塊類實例, 如果模塊沒有被請求,該方法會返回空,注意不需要手動創建一個模塊類,因為手動創建的和Yii處理請求時自動創建的不同。
補充: 當開發模塊時,你不能假定模塊使用固定的ID,因為在應用或其他沒模塊中,模塊可能會對應到任意的ID, 為了獲取模塊ID,應使用上述代碼獲取模塊實例,然后通過$module->id獲取模塊ID。
也可以使用如下方式訪問模塊實例:
// 獲取ID為 "forum" 的模塊 $module = \Yii::$app->getModule('forum'); // 獲取處理當前請求控制器所屬的模塊 $module = \Yii::$app->controller->module;
第一種方式僅在你知道模塊ID的情況下有效,第二種方式在你知道處理請求的控制器下使用。
一旦獲取到模塊實例,可訪問注冊到模塊的參數和組件,例如:
$maxPostCount = $module->params['maxPostCount'];
引導啟動模塊
有些模塊在每個請求下都有運行, [[yii\debug\Module|debug]] 模塊就是這種, 為此將這種模塊加入到應用主體的 [[yii\base\Application::bootstrap|bootstrap]] 屬性中。
例如,如下示例的應用主體配置會確保debug模塊每次都被加載:
[ 'bootstrap' => [ 'debug', ], 'modules' => [ 'debug' => 'yii\debug\Module', ], ]
模塊嵌套
模塊可無限級嵌套,也就是說,模塊可以包含另一個包含模塊的模塊,我們稱前者為父模塊,后者為子模塊, 子模塊必須在父模塊的[[yii\base\Module::modules|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中子模塊admin中dashboard控制器的index操作。
最佳實踐
模塊在大型項目中常備使用,這些項目的特性可分組,每個組包含一些強相關的特性, 每個特性組可以做成一個模塊由特定的開發人員和開發組來開發和維護。
在特性組上,使用模塊也是重用代碼的好方式,一些常用特性,如用戶管理,評論管理,可以開發成模塊, 這樣在相關項目中非常容易被重用。
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://www.wangchenghua.com/post/2837/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料