2 · курс
0%
Главная/🏗Структура приложения

08Модули

Как упаковать часть функциональности в самостоятельный модуль: структура, класс Module, маршруты, доступ к модулю, вложенность и URL-правила.

⏱ ~4 мин 📚 1 глава руководства

Модуль — это «приложение в приложении»: свои контроллеры, модели, представления, компоненты и параметры. Модули не запускаются отдельно, но их удобно переиспользовать между проектами: форум, блог, админка, версия API.

Структура#

modules/forum/
    Module.php                  класс модуля (обязателен, в корне модуля)
    controllers/
        DefaultController.php   контроллер по умолчанию
        PostController.php
    models/
    views/
        layouts/                шаблоны модуля
        default/index.php       представления контроллера default
        post/
    migrations/
    config.php                  необязательно: конфигурация модуля

Класс модуля#

modules/forum/Module.phpPHP
namespace app\modules\forum;

class Module extends \yii\base\Module
{
    public $controllerNamespace = 'app\modules\forum\controllers';   // так и по умолчанию

    public function init()
    {
        parent::init();
        $this->params['foo'] = 'bar';
        \Yii::configure($this, require __DIR__ . '/config.php');   // components, params… из файла

        if (\Yii::$app instanceof \yii\console\Application) {
            $this->controllerNamespace = 'app\modules\forum\commands';   // консольные команды модуля
        }
    }
}

Модуль — тоже Service Locator: в нём можно регистрировать компоненты ('components' => [...]) и параметры, доступные как $module->params.

Контроллеры и представления модуля#

modules/forum/controllers/PostController.phpPHP
namespace app\modules\forum\controllers;

class PostController extends \yii\web\Controller
{
    public function actionIndex()
    {
        return $this->render('index');   // modules/forum/views/post/index.php
    }
}

Шаблон модуля задаётся свойством layout модуля и ищется в views/layouts модуля; если не задан — используется шаблон приложения. Соглашения об именах те же, что у контроллеров приложения; отклонения — через controllerMap модуля.

Подключение и маршруты#

config/web.phpPHP
'modules' => [
    'forum' => [
        'class' => 'app\modules\forum\Module',
        'params' => ['postsPerPage' => 20],
    ],
],

Маршрут внутри модуля начинается с его ID: forum/post/index → PostController::actionIndex() модуля forum. Маршрут forum целиком → defaultRoute модуля (default) → DefaultController::actionIndex().

Доступ к модулю из кода#

PHP
$module = \Yii::$app->getModule('forum');          // по ID
$module = \Yii::$app->controller->module;          // модуль текущего контроллера
$module = \app\modules\forum\Module::getInstance();  // экземпляр, созданный для текущего запроса (или null)

$max = $module->params['postsPerPage'];

Предзагрузка и URL-правила#

Модуль создаётся лениво — при первом обращении по маршруту. Если он должен работать в каждом запросе (например, добавлять свои правила ЧПУ), укажите его в bootstrap и реализуйте BootstrapInterface:

PHP
'bootstrap' => ['forum'],
PHP
class Module extends \yii\base\Module implements \yii\base\BootstrapInterface
{
    public function bootstrap($app)
    {
        $app->urlManager->addRules([
            ['class' => 'yii\web\GroupUrlRule', 'prefix' => 'forum', 'rules' => [
                'posts' => 'post/index',
                'post/<id:\d+>' => 'post/view',
            ]],
        ], false);
    }
}

Вложенные модули#

PHP
class Module extends \yii\base\Module
{
    public function init()
    {
        parent::init();
        $this->modules = [
            'admin' => ['class' => 'app\modules\forum\modules\admin\Module'],
        ];
    }
}

Маршрут: forum/admin/dashboard/index. getModule('admin') работает только для прямых потомков; все загруженные модули — в Yii::$app->loadedModules.

Когда нужны модули#

  • Крупное приложение, которое делится на области ответственности (каждую ведёт своя команда).
  • Функциональность, которую вы будете переносить между проектами: пользователи, комментарии, платежи.
  • Версии REST API (v1, v2) — см. REST: версионирование.

Если группировать контроллеры хочется, а всё остальное общее, — достаточно подпапки в controllers/ (маршрут admin/post), модуль не нужен.

Проверь себя4

defaultRoute модуля (по умолчанию default) и defaultAction контроллера — DefaultController::actionIndex().

Модуль создаётся при разборе маршрута, когда UrlManager::parseRequest() уже отработал. Правила добавляют в bootstrap() модуля, включённого в bootstrap приложения.

MyModule::getInstance() — вернёт экземпляр, обслуживающий текущий запрос, или Yii::$app->controller->module.

Приложение — потомок yii\base\Module: у обоих есть components, params, modules, controllerNamespace, layout, события beforeAction/afterAction.