structure-modules.md 14.9 KB
Newer Older
1 2
モジュール
==========
3

4 5 6 7 8 9
モジュールは、[モデル](structure-models.md)[ビュー](structure-views.md)[コントローラ](structure-controllers.md)
およびその他の支援コンポーネントから構成される自己充足的なソフトウェアのユニットです。
モジュールが [アプリケーション](structure-applications.md) にインストールされている場合、
エンドユーザはモジュールのコントローラにアクセスする事が出来ます。これらのことを理由として、
モジュールは小さなアプリケーションと見なされることがよくあります。しかし、モジュールは単独では配置できず、
アプリケーションの中に存在しなければならないという点で [アプリケーション](structure-applications.md) とは異なります。
10 11


12
## モジュールを作成する <a name="creating-modules"></a>
13

14 15 16 17
モジュールは、モジュールの [[yii\base\Module::basePath|ベースパス]] と呼ばれるディレクトリとして組織されます。
このディレクトリの中に、ちょうどアプリケーションの場合と同じように、`controllers``models``views`
のようなサブディレクトリが存在して、コントローラ、モデル、ビュー、その他のコードを収納しています。
次の例は、モジュール内の中身を示すものです:
18 19 20

```
forum/
21 22 23 24 25 26 27 28
    Module.php                   モジュールクラスファイル
    controllers/                 コントローラクラスファイルを含む
        DefaultController.php    デフォルトのコントローラクラスファイル
    models/                      モデルクラスファイルを含む
    views/                       コントローラのビューとレイアウトのファイルを含む
        layouts/                 レイアウトのビューファイルを含む
        default/                 DefaultController のためのビューファイルを含む
            index.php            index ビューファイル
29 30 31
```


32
### モジュールクラス <a name="module-classes"></a>
33

34 35 36
全てのモジュールは [[yii\base\Module]] から拡張したユニークなモジュールクラスを持たなければなりません。
モジュールクラスは、モジュールの [[yii\base\Module::basePath|ベースパス]] 直下に配置されて
[オートロード可能](concept-autoloading.md) になっていなければなりません。
37
モジュールがアクセスされたとき、対応するモジュールクラスの単一のインスタンスが作成されます。
38 39
[アプリケーションのインスタンス](structure-applications.md) と同じように、モジュールのインスタンスは
モジュール内のコードがデータとコンポーネントを共有するために使用されます。
40

41
次のコードは、モジュールクラスがどのように見えるかを示す例です:
42 43 44 45 46 47 48 49 50 51 52

```php
namespace app\modules\forum;

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

        $this->params['foo'] = 'bar';
53
        // ... 他の初期化コード ...
54 55 56 57
    }
}
```

58 59 60
`init` メソッドがモジュールのプロパティを初期化するためのコードをたくさん含む場合は、それを
[コンフィギュレーション](concept-configurations.md) の形で保存し、`init()` の中で次のコードを使って
読み出すことも可能です:
61 62 63 64 65

```php
public function init()
{
    parent::init();
66
    // config.php からロードしたコンフィギュレーションでモジュールを初期化する
67 68 69 70
    \Yii::configure($this, require(__DIR__ . '/config.php'));
}
```

71 72 73
ここで、コンフィギュレーションファイル `config.php` は、
[アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の場合と同じように、
次のような内容を含むことが出来ます。
74 75 76 77 78

```php
<?php
return [
    'components' => [
79
        // コンポーネントのコンフィギュレーションのリスト
80 81
    ],
    'params' => [
82
        // パラメータのリスト
83 84 85 86 87
    ],
];
```


88
### モジュール内のコントローラ <a name="controllers-in-modules"></a>
89

90 91 92 93 94
モジュールの中でコントローラを作成するときは、コントローラクラスをモジュールクラスの名前空間の `controllers`
サブ名前空間に置くことが規約です。このことは、同時に、コントローラのクラスファイルをモジュールの
[[yii\base\Module::basePath|ベースパス]] 内の `controllers` ディレクトリに置くべきことをも意味します。
例えば、前の項で示された `forum` モジュールの中で `post` コントローラを作成するためには、次のようにして
コントローラを宣言しなければなりません:
95 96 97 98 99 100 101 102 103 104 105 106

```php
namespace app\modules\forum\controllers;

use yii\web\Controller;

class PostController extends Controller
{
    // ...
}
```

107 108 109 110
コントローラクラスの名前空間は、[[yii\base\Module::controllerNamespace]] プロパティを構成してカスタマイズすることが出来ます。
いくつかのコントローラがこの名前空間の外にある場合でも、[[yii\base\Module::controllerMap]] プロパティを構成することによって、
それらをアクセス可能にすることが出来ます。これは、[アプリケーションでのコントローラマップ](structure-applications.md#controller-map)
の場合と同様です。
111 112


113
### モジュール内のビュー <a name="views-in-modules"></a>
114

115 116 117 118
モジュール内のビューは、モジュールの [[yii\base\Module::basePath|ベースパス]] 内の `views` ディレクトリに置かれなくてはなりません。
モジュール内のコントローラによってレンダリングされるビューは、ディレクトリ `views/ControllerID` の下に置きます。ここで、
`ControllerID`[コントローラ ID](structure-controllers.md#routes) を指します。例えば、コントローラクラスが `PostController`
である場合、ディレクトリはモジュールの [[yii\base\Module::basePath|ベースパス]] の中の `views/post` となります。
119

120 121 122 123
モジュールは、そのモジュールのコントローラによってレンダリングされるビューに適用される [レイアウト](structure-views.md#layouts)
を指定することが出来ます。レイアウトは、既定では `views/layouts` ディレクトリに置かれなければならず、また、
[[yii\base\Module::layout]] プロパティがレイアウトの名前を指すように構成しなければなりません。
`layout` プロパティを構成しない場合は、アプリケーションのレイアウトが代りに使用されます。
124 125


126
## モジュールを使う <a name="using-modules"></a>
127

128 129 130 131
アプリケーションの中でモジュールを使うためには、アプリケーションの [[yii\base\Application::modules|modules]] プロパティのリストに
そのモジュールを載せてアプリケーションを構成するだけで大丈夫です。次のコードは、
[アプリケーションのコンフィギュレーション](structure-applications.md#application-configurations) の中で
`forum` モジュールを使うようにするものです:
132 133 134 135 136 137

```php
[
    'modules' => [
        'forum' => [
            'class' => 'app\modules\forum\Module',
138
            // ... モジュールのその他のコンフィギュレーション ...
139 140 141 142 143
        ],
    ],
]
```

144 145 146
[[yii\base\Application::modules|modules]] プロパティは、モジュールのコンフィギュレーションの配列を取ります。各配列のキーは、
アプリケーションの全てのモジュールの中でそのモジュールを特定するためのユニークな *モジュール ID* を表します。そして、
対応する配列の値は、そのモジュールを作成するための [コンフィギュレーション](concept-configurations.md) です。
147 148


149
### ルート <a name="routes"></a>
150

151 152 153 154 155 156 157
アプリケーションの中のコントローラをアクセスするのと同じように、[ルート](structure-controllers.md#routes)
がモジュールの中のコントローラを指し示すために使われます。モジュール内のコントローラのルートは、モジュール ID で始まり、
コントローラ ID、アクション ID と続くものでなければなりません。例えば、アプリケーションが `forum` という名前のモジュールを
使用している場合、`forum/post/index` というルートは、`forum` モジュール内の `post` コントローラの `index` アクションを表します。
ルートがモジュール ID だけを含む場合は、[[yii\base\Module::defaultRoute]] プロパティ (その既定値は `default` です) が、
どのコントローラ/アクションが使用されるべきかを決定します。これは、`forum` というルートは `forum` モジュール内の
`default` コントローラを表すという意味です。
158 159


160
### モジュールにアクセスする <a name="accessing-modules"></a>
161

162 163
モジュール内において、モジュール ID や、モジュールのパラメータ、モジュールのコンポーネントなどにアクセスするために、
[モジュールクラス](#module-classes) のインスタンスを取得する必要があることがよくあります。次の文を使ってそうすることが出来ます:
164 165 166 167 168

```php
$module = MyModuleClass::getInstance();
```

169 170 171 172
ここで `MyModuleClass` は、関心を持っているモジュールクラスの名前を指します。`getInstance()` メソッドは、
現在リクエストされているモジュールクラスのインスタンスを返します。モジュールがリクエストされていない場合は、
このメソッドは null を返します。モジュールクラスの新しいインスタンスを手動で作成しようとしてはいけないことに注意してください。
そのインスタンスは、リクエストに対するレスポンスとして Yii によって作成されたインスタンスとは別のものになります。
173

174 175 176 177
> Info|情報: モジュールを開発するとき、モジュールが固定の ID を使うと仮定してはいけません。なぜなら、モジュールは、
  アプリケーションや他のモジュールの中で使うときに、任意の ID と結び付けることが出来るからです。
  モジュール ID を取得するためには、上記の方法を使って最初にモジュールのインスタンスを取得し、そして `$module->id`
  によって ID を取得しなければなりません。
178

179
モジュールのインスタンスにアクセスするためには、次の二つの方法を使うことも出来ます:
180 181

```php
182
// ID が "forum" である子モジュールを取得する
183 184
$module = \Yii::$app->getModule('forum');

185
// 現在リクエストされているコントローラが属するモジュールを取得する
186 187 188
$module = \Yii::$app->controller->module;
```

189 190
最初の方法は、モジュール ID を知っている時しか役に立ちません。一方、第二の方法は、
リクエストされているコントローラについて知っている場合に使うのに最適な方法です。
191

192 193
いったんモジュールのインスタンスをとらえれば、モジュールに登録されたパラメータやコンポーネントにアクセスすることが可能になります。
例えば、
194 195 196 197 198 199

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


200
### モジュールをブートストラップする <a name="bootstrapping-modules"></a>
201

202 203
いくつかのモジュールは、全てのリクエストで毎回走らせる必要があります。[[yii\debug\Module|デバッグ]] モジュールがその一例です。
そうするためには、そのようなモジュールをアプリケーションの [[yii\base\Application::bootstrap|bootstrap]] プロパティのリストに挙げます。
204

205
例えば、次のアプリケーションのコンフィギュレーションは、`debug` モジュールが常にロードされることを保証するものです:
206 207 208 209 210 211 212 213 214 215 216 217 218 219

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

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


220
## 入れ子のモジュール <a name="nested-modules"></a>
221

222 223 224 225
モジュールはレベルの制限無く入れ子にすることが出来ます。つまり、モジュールは別のモジュールを含むことが出来、
その含まれたモジュールもさらに別のモジュールを含むことが出来ます。含む側を *親モジュール*、含まれる側を *子モジュール*
と呼びます。子モジュールは、親モジュールの [[yii\base\Module::modules|modules]] プロパティの中で宣言されなければなりません。
例えば、
226 227 228 229 230 231 232 233 234 235 236 237

```php
namespace app\modules\forum;

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

        $this->modules = [
            'admin' => [
238
                // ここはもっと短い名前空間の使用を考慮すべきだ!
239 240 241 242 243 244 245
                'class' => 'app\modules\forum\modules\admin\Module',
            ],
        ];
    }
}
```

246 247 248
入れ子にされたモジュールの中にあるコントローラのルートは、全ての祖先のモジュールの ID を含まなければなりません。
例えば、`forum/admin/dashboard/index` というルートは、`forum` モジュールの子モジュールである `admin` モジュールの
`dashboard` コントローラの `index` アクションを表します。
249

250 251 252
> Info|情報: [[yii\base\Module::getModule()|getModule()]] メソッドは、親モジュールに直接属する子モジュールだけを返します。
[[yii\base\Application::loadedModules]] プロパティがロードされた全てのモジュールのリストを保持しています。
このリストには、直接の子と孫以下の両方のモジュールが含まれ、クラス名によってインデックスされています。
253 254


255
## 最善の慣行 <a name="best-practices"></a>
256

257 258
モジュールは、それぞれ密接に関係する一連の機能を含む数個のグループに分割できるような、規模の大きなアプリケーションに
最も適しています。そのような機能グループをそれぞれモジュールとして、特定の個人やチームによって開発することが出来ます。
259

260 261 262
モジュールは、また、機能グループレベルでコードを再利用するための良い方法でもあります。ある種のよく使われる機能、
例えばユーザ管理やコメント管理などは、全て、将来のプロジェクトで容易に再利用できるように、モジュールの形式で
開発することが出来ます。