Представьте, что вы строите дом. Если класть кирпичи как попало, стены рухнут. В программировании то же самое. Без модульной архитектуры ваше приложение превращается в кашу из файлов. Сегодня я покажу, как навести порядок в Yii2 с помощью модулей. Вы узнаете, как разбить проект на независимые блоки, упростить поддержку и не сойти с ума.
Что такое модуль в Yii2 и зачем он нужен?
Модуль в Yii2 — это мини-приложение внутри основного приложения. У него есть свои контроллеры, модели, представления и конфигурация. Представьте, что вы собираете конструктор Lego. Каждый модуль — это отдельный блок. Вы можете его добавить, убрать или заменить, не ломая остальное.
Зачем это нужно? Допустим, у вас интернет-магазин. Есть каталог, корзина, админка, пользователи. Если всё свалить в одну кучу, через год вы проклянете день, когда начали проект. Модули решают эту проблему. Они изолируют функционал. Например, модуль "Каталог" отвечает только за товары. Модуль "Корзина" — за заказы. Они общаются через события или сервисы, но не лезут в код друг друга.
Ещё один плюс — переиспользование. Написали модуль для рассылки писем? Вставили его в другой проект — и готово. Экономия времени и нервов.
Структура модуля: с чего начать?
Создание модуля начинается с папки. В Yii2 модули обычно лежат в modules/. Давайте создадим простой модуль для управления статьями блога.
// Структура папок:
modules/
blog/
controllers/
DefaultController.php
models/
Article.php
views/
default/
index.php
Module.php
config.php
Главный файл — Module.php. Он наследуется от yii\base\Module. В нём мы настраиваем пространство имён и подключаем конфигурацию.
<?php
namespace app\modules\blog;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'app\modules\blog\controllers';
public function init()
{
parent::init();
// Здесь можно загрузить конфиг
$this->setAliases([
'@blog' => __DIR__,
]);
}
}
Теперь нужно зарегистрировать модуль в конфигурации приложения. Откройте config/web.php и добавьте:
'modules' => [
'blog' => [
'class' => 'app\modules\blog\Module',
// Можно передать свои параметры
'params' => [
'pageSize' => 20,
],
],
],
Всё. Теперь по адресу /blog/default/index будет доступен контроллер. Обратите внимание: URL строится как /moduleId/controllerId/actionId.
Контроллеры и модели внутри модуля
Контроллеры в модуле ничем не отличаются от обычных. Единственное — они должны быть в пространстве имён модуля. Давайте создадим контроллер для списка статей.
<?php
namespace app\modules\blog\controllers;
use yii\web\Controller;
use app\modules\blog\models\Article;
class DefaultController extends Controller
{
public function actionIndex()
{
$articles = Article::find()->all();
return $this->render('index', ['articles' => $articles]);
}
}
Модели — тоже обычные. Только лежат в папке models модуля. Например, модель Article может работать с таблицей blog_articles. Чтобы не путаться, я рекомендую именовать таблицы с префиксом модуля.
<?php
namespace app\modules\blog\models;
use yii\db\ActiveRecord;
class Article extends ActiveRecord
{
public static function tableName()
{
return 'blog_articles';
}
}
Представления лежат в views/controllerId/. В нашем случае — views/default/index.php. Внутри можно использовать обычный HTML и PHP.
<h1>Список статей</h1>
<ul>
<?php foreach ($articles as $article): ?>
<li><?= Html::encode($article->title) ?></li>
<?php endforeach; ?>
</ul>
Как модули общаются между собой?
Прямые вызовы методов из другого модуля — зло. Вместо этого используйте события или сервисный слой. Например, модуль "Корзина" хочет узнать цену товара из модуля "Каталог". Создайте интерфейс и реализуйте его в модуле.
Пример через события:
// В модуле catalog при сохранении товара
\Yii::$app->trigger('catalog.afterSave', new \yii\base\Event(['sender' => $this]));
// В модуле cart подписываемся
\Yii::$app->on('catalog.afterSave', function ($event) {
// Обновить кэш корзины
});
Или через Dependency Injection. Создайте интерфейс PriceProviderInterface и зарегистрируйте его в контейнере.
// В конфиге приложения
\Yii::$container->set('app\interfaces\PriceProviderInterface', [
'class' => 'app\modules\catalog\services\PriceProvider',
]);
// В модуле cart используем
$priceProvider = \Yii::$container->get('app\interfaces\PriceProviderInterface');
$price = $priceProvider->getPrice($productId);
ModuleService, который предоставляет методы для работы с модулями. Это упростит тестирование и замену модулей.
Миграции и настройки модуля
Каждый модуль может иметь свои миграции. Создайте папку migrations внутри модуля. Затем в конфиге приложения укажите путь к миграциям модуля.
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\controllers\MigrateController',
'migrationPath' => [
'@app/migrations',
'@blog/migrations', // путь к миграциям модуля
],
],
],
Также модуль может иметь свои конфигурационные файлы. Например, config.php внутри модуля, который подгружается в init(). Это удобно для настройки правил URL или компонентов.
| Параметр | Описание | Пример |
|---|---|---|
| controllerNamespace | Пространство имён контроллеров | app\modules\blog\controllers |
| defaultRoute | Контроллер по умолчанию | default |
| params | Пользовательские параметры | ['pageSize' => 20] |
Что в итоге?
Модульная архитектура в Yii2 — это не дань моде, а необходимость для больших проектов. Вы получаете чистый код, лёгкую поддержку и возможность переиспользовать модули. Начните с малого: выделите один функциональный блок в модуль. Например, форму обратной связи или блог. Со временем вы увидите, как проект становится прозрачным и управляемым.
Главное — не пытайтесь сделать всё идеально сразу. Модульность должна расти естественно. Если чувствуете, что код начинает путаться — значит, пора делить на модули. Удачи в кодинге!

