2 フォロワー

モジュール

モジュールは、モデルビューコントローラ、およびその他のサポートコンポーネントで構成される自己完結型のソフトウェアユニットです。エンドユーザーは、アプリケーションにインストールされているモジュールのコントローラにアクセスできます。これらの理由から、モジュールはミニアプリケーションと見なされることがよくあります。モジュールは、モジュールが単独でデプロイできず、アプリケーション内に存在する必要があるという点で、アプリケーションとは異なります。

モジュールの作成

モジュールは、モジュールのベースパスと呼ばれるディレクトリとして編成されています。ディレクトリ内には、アプリケーションのように、コントローラ、モデル、ビュー、その他のコードを保持する controllersmodelsviews などのサブディレクトリがあります。次の例は、モジュール内のコンテンツを示しています。

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)が、使用するコントローラ/アクションを決定します。これは、ルート forumforum モジュール内の 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 で編集する !