モジュールは、モデル、ビュー、コントローラ、およびその他のサポートコンポーネントで構成される自己完結型のソフトウェアユニットです。エンドユーザーは、アプリケーションにインストールされているモジュールのコントローラにアクセスできます。これらの理由から、モジュールはミニアプリケーションと見なされることがよくあります。モジュールは、モジュールが単独でデプロイできず、アプリケーション内に存在する必要があるという点で、アプリケーションとは異なります。
モジュールは、モジュールのベースパスと呼ばれるディレクトリとして編成されています。ディレクトリ内には、アプリケーションのように、コントローラ、モデル、ビュー、その他のコードを保持する controllers
、models
、views
などのサブディレクトリがあります。次の例は、モジュール内のコンテンツを示しています。
forum/
Module.php the module class file
controllers/ containing controller class files
DefaultController.php the default controller class file
models/ containing model class files
views/ containing controller view and layout files
layouts/ containing layout view files
default/ containing view files for DefaultController
index.php the index view file
各モジュールには、yii\base\Module を拡張する一意のモジュールクラスが必要です。クラスは、モジュールのベースパスの直下に配置し、オートロード可能にする必要があります。モジュールにアクセスすると、対応するモジュールクラスの単一のインスタンスが作成されます。アプリケーションインスタンスと同様に、モジュールインスタンスは、モジュール内のコードのデータとコンポーネントを共有するために使用されます。
以下は、モジュールクラスがどのように見えるかの例です。
namespace app\modules\forum;
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
$this->params['foo'] = 'bar';
// ... other initialization code ...
}
}
init()
メソッドにモジュールのプロパティを初期化するコードが多く含まれている場合は、設定として保存し、init()
で次のコードを使用してロードすることもできます。
public function init()
{
parent::init();
// initialize the module with the configuration loaded from config.php
\Yii::configure($this, require __DIR__ . '/config.php');
}
設定ファイル config.php
には、アプリケーション設定と同様の以下の内容が含まれる場合があります。
<?php
return [
'components' => [
// list of component configurations
],
'params' => [
// list of parameters
],
];
モジュール内にコントローラを作成する場合、慣例として、コントローラクラスをモジュールクラスの名前空間の 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
ディレクトリに配置する必要があります。モジュール内のコントローラによってレンダリングされるビューは、views/ControllerID
ディレクトリの下に配置する必要があります。ここで、ControllerID
はコントローラIDを指します。例えば、コントローラクラスが PostController
の場合、ディレクトリはモジュールのベースパス内の views/post
になります。
モジュールは、モジュールのコントローラによってレンダリングされるビューに適用されるレイアウトを指定できます。レイアウトは、デフォルトでは views/layouts
ディレクトリに配置し、レイアウト名を指すように yii\base\Module::$layout プロパティを設定する必要があります。layout
プロパティを設定しない場合、代わりにアプリケーションのレイアウトが使用されます。
モジュールは、コンソールモードで使用できるコマンドを宣言することもできます。
コマンドラインユーティリティがコマンドを認識するためには、Yii がコンソールモードで実行されているときに yii\base\Module::$controllerNamespace プロパティを変更し、コマンドの名前空間を指すようにする必要があります。
これを実現する1つの方法は、モジュールの init()
メソッドで Yii アプリケーションのインスタンスタイプをテストすることです。
public function init()
{
parent::init();
if (Yii::$app instanceof \yii\console\Application) {
$this->controllerNamespace = 'app\modules\forum\commands';
}
}
すると、次のルートを使用してコマンドラインからコマンドを利用できるようになります。
yii <module_id>/<command>/<sub_command>
アプリケーションでモジュールを使用するには、アプリケーションの modules プロパティにモジュールをリストして、アプリケーションを設定するだけです。アプリケーション設定の以下のコードは、forum
モジュールを使用しています。
[
'modules' => [
'forum' => [
'class' => 'app\modules\forum\Module',
// ... other configurations for the module ...
],
],
]
情報: モジュールのコンソールコマンドを接続するには、コンソールアプリケーションの設定にも含める必要があります。
modules プロパティは、モジュール設定の配列を受け取ります。各配列キーは、アプリケーション内のすべてのモジュール間でモジュールを一意に識別するモジュールIDを表し、対応する配列値はモジュールを作成するための設定です。
アプリケーション内のコントローラへのアクセスと同様に、ルートはモジュール内のコントローラをアドレス指定するために使用されます。モジュール内のコントローラのルートは、モジュールIDの後にコントローラIDとアクションIDを続けて指定する必要があります。例えば、アプリケーションが forum
という名前のモジュールを使用している場合、ルート forum/post/index
は、モジュール内の post
コントローラの index
アクションを表します。ルートにモジュールIDのみが含まれている場合、yii\base\Module::$defaultRoute プロパティ(デフォルトは default
)が、使用するコントローラ/アクションを決定します。これは、ルート forum
が forum
モジュール内の default
コントローラを表すことを意味します。
モジュールの URL マネージャルールは、yii\web\UrlManager::parseRequest() が起動される前に追加する必要があります。つまり、モジュールの init()
で行うことはできません。ルートが既に処理されたときにモジュールが初期化されるためです。したがって、ルールは ブートストラップステージで追加する必要があります。モジュールの URL ルールを yii\web\GroupUrlRule でラップすることも良い習慣です。
モジュールが API のバージョン管理に使用される場合、その URL ルールはアプリケーション構成の urlManager
セクションに直接追加する必要があります。
モジュール内では、モジュール ID、モジュールパラメータ、モジュールコンポーネントなどにアクセスできるように、モジュールクラスのインスタンスを取得する必要があることがよくあります。次のステートメントを使用することで実行できます。
$module = MyModuleClass::getInstance();
ここで、MyModuleClass
は、関心のあるモジュールクラスの名前を指します。getInstance()
メソッドは、モジュールクラスの現在リクエストされているインスタンスを返します。モジュールがリクエストされていない場合、メソッドは null
を返します。リクエストに応じて Yii によって作成されたインスタンスとは異なるため、モジュールクラスの新しいインスタンスを手動で作成しないように注意してください。
情報: モジュールを開発する場合、モジュールが固定 ID を使用することを前提としないでください。これは、モジュールがアプリケーション内または別のモジュール内で使用されるときに、任意の ID に関連付けられる可能性があるためです。モジュール ID を取得するには、まず上記の方法を使用してモジュールインスタンスを取得し、次に
$module->id
を介して ID を取得する必要があります。
次のアプローチを使用してモジュールのインスタンスにアクセスすることもできます。
// get the child module whose ID is "forum"
$module = \Yii::$app->getModule('forum');
// get the module to which the currently requested controller belongs
$module = \Yii::$app->controller->module;
最初のアプローチは、モジュールIDがわかっている場合にのみ役立ちますが、2番目のアプローチは、リクエストされているコントローラについて知っている場合に最適です。
モジュールインスタンスを取得したら、モジュールに登録されているパラメータとコンポーネントにアクセスできます。例:
$maxPostCount = $module->params['maxPostCount'];
一部のモジュールは、すべてのリクエストに対して実行する必要がある場合があります。yii\debug\Module モジュールがそのような例です。これを行うには、そのようなモジュールの ID をアプリケーションの bootstrap プロパティにリストします。
例えば、次のアプリケーション設定では、debug
モジュールが常にロードされるようにします。
[
'bootstrap' => [
'debug',
],
'modules' => [
'debug' => 'yii\debug\Module',
],
]
モジュールは、無制限のレベルでネストできます。つまり、モジュールには別のモジュールを含めることができ、さらに別のモジュールを含めることができます。前者を親モジュール、後者を子モジュールと呼びます。子モジュールは、親モジュールの modules プロパティで宣言する必要があります。例:
namespace app\modules\forum;
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
$this->modules = [
'admin' => [
// you should consider using a shorter namespace here!
'class' => 'app\modules\forum\modules\admin\Module',
],
];
}
}
ネストされたモジュール内のコントローラの場合、そのルートには、すべての祖先モジュールの ID を含める必要があります。例えば、ルート forum/admin/dashboard/index
は、forum
モジュールの子モジュールである admin
モジュール内の dashboard
コントローラの index
アクションを表します。
情報: getModule() メソッドは、親に直接属する子モジュールのみを返します。yii\base\Application::$loadedModules プロパティは、直接の子とネストされたものを含め、ロードされたモジュールのリストをクラス名でインデックス化して保持します。
バージョン 2.0.13 以降、モジュールはツリー走査をサポートしています。これにより、モジュール開発者は、モジュールであるサービスロケータを介して(アプリケーション)コンポーネントを参照できます。つまり、Yii::$app->get('db')
よりも $module->get('db')
を使用することをお勧めします。モジュールのユーザは、別のコンポーネント(構成)が必要な場合に、モジュールに使用する特定のコンポーネントを指定できます。
例えば、このアプリケーション構成の一部を考えてみましょう。
'components' => [
'db' => [
'tablePrefix' => 'main_',
'class' => Connection::class,
'enableQueryCache' => false
],
],
'modules' => [
'mymodule' => [
'components' => [
'db' => [
'tablePrefix' => 'module_',
'class' => Connection::class
],
],
],
],
アプリケーションのデータベーステーブルには main_
がプレフィックスとして付けられ、すべてのモジュールテーブルには module_
がプレフィックスとして付けられます。上記の構成はマージされないことに注意してください。例えば、モジュールのコンポーネントはデフォルト値であるため、クエリキャッシュが有効になります。
モジュールは、機能がいくつかのグループに分割でき、それぞれが密接に関連する機能のセットで構成される大規模なアプリケーションで最もよく使用されます。このような各機能グループは、特定の開発者またはチームによって開発および保守されるモジュールとして開発できます。
モジュールは、機能グループレベルでコードを再利用するのにも適した方法です。ユーザ管理、コメント管理など、一般的に使用される機能はすべてモジュールとして開発できるため、今後のプロジェクトで簡単に再利用できます。
タイプミスを見つけたり、このページを改善する必要があると思われますか?
github で編集する !
カスタムモジュールのブートストラップクラスまたはモジュールのルールクラス内で取得しようとすると、常にモジュール内で null が返されます。
コードが正しくありません。
$this
->\Yii::$app
変更前
public function init() { parent::init(); // initialize the module with the configuration loaded from config.php \Yii::configure($this, require __DIR__ . '/config.php'); }
修正後
public function init() { parent::init(); // initialize the module with the configuration loaded from config.php \Yii::configure(\Yii::$app, require __DIR__ . '/config.php'); }
最後に、私の
config.php
<?php return [ 'components' => [ 'response' => [ 'class' => 'yii\web\Response', 'format' => \yii\web\Response::FORMAT_JSON, 'charset' => 'UTF-8', ], ], 'params' => [ // list of parameters ], ];
このページに示されているコードは、アプリケーションオブジェクトではなく、モジュールオブジェクトを初期化しているため、正しいです。
\Yii::configure($this, require __DIR__ . '/config.php');
コメントするには、サインアップ または ログインしてください。