Если вы когда-нибудь пытались развивать проект, который начинался как «просто сайт-визитка», а через год превратился в монстра с десятками контроллеров и моделей, то знаете: без чёткой структуры код превращается в кашу. Сегодня расскажу, как этого избежать с помощью модульной архитектуры в Yii2. Спойлер: это проще, чем кажется, и спасёт вам нервы.
Модуль в Yii2 — это как отдельная комната в квартире. В ней есть своя мебель (контроллеры), свои вещи (модели), свои правила (конфиги). И всё это изолировано от других комнат, но при этом легко доступно через общий коридор — приложение. Звучит логично, правда? Давайте разберёмся, как это реализовать на практике.
Почему модули — это не роскошь, а необходимость
Когда вы работаете над проектом, который планирует расти (а кто не планирует?), рано или поздно столкнётесь с проблемой: файлы разрастаются, связи между ними запутываются, а правки в одном месте ломают другое. Модульная структура решает эти проблемы раз и навсегда.
- Изоляция. Каждый модуль отвечает за свою часть функциональности. Например, модуль «каталог» не знает о существовании модуля «корзина» и не должен в него лезть.
- Переиспользование. Модуль можно легко перенести в другой проект или отключить, если он больше не нужен.
- Тестирование. Модули можно тестировать независимо друг от друга, что упрощает поиск ошибок.
- Командная работа. Если над проектом работает несколько разработчиков, каждый может заниматься своим модулем, не конфликтуя с другими.
Без модулей вы рано или поздно упрётесь в «спагетти-код», где всё связано со всем. Поверьте, я видел такое не раз. И это не лечится, кроме как полной переработкой.
Создаём модуль: пошаговая инструкция
В Yii2 модуль — это обычная директория с файлами. Создавать его можно вручную или через консольную команду. Покажу оба способа.
Способ 1: Через консоль (быстро и удобно)
php yii gii/module --moduleID=blog --moduleClass=app\modules\blog\BlogModule
Эта команда создаст модуль с именем «blog» в папке modules. Внутри появятся стандартные папки: controllers, models, views и файл BlogModule.php.
Способ 2: Вручную (для полного контроля)
- Создайте папку
modulesв корне приложения, если её ещё нет. - Внутри создайте папку модуля, например
blog. - Создайте файл
BlogModule.phpс классом модуля.
namespace app\modules\blog;
class BlogModule extends \yii\base\Module
{
public $controllerNamespace = 'app\modules\blog\controllers';
public function init()
{
parent::init();
// здесь можно инициализировать модуль
}
}
Теперь подключите модуль в конфигурации приложения. Откройте config/web.php и добавьте:
'modules' => [
'blog' => [
'class' => 'app\modules\blog\BlogModule',
],
],
Готово! Модуль доступен по адресу /blog. Если вы создали контроллер PostController с действием index, то адрес будет /blog/post/index.
| Параметр | Описание |
|---|---|
| controllerNamespace | Указывает, где искать контроллеры модуля. |
| defaultRoute | Определяет контроллер и действие по умолчанию (например, 'post/index'). |
| layout | Можно задать свой макет для модуля, если нужно. |
Как правильно организовать код внутри модуля
Просто создать папки недостаточно. Чтобы модуль был по-настоящему масштабируемым, нужно продумать, что куда класть. Вот моя схема, проверенная годами.
- controllers — только контроллеры. Никакой бизнес-логики, только обработка запросов.
- models — модели, которые отвечают за работу с базой данных (ActiveRecord).
- views — представления (HTML-шаблоны).
- widgets — виджеты, если они специфичны для модуля.
- components — вспомогательные классы, например, сервисы или хелперы.
- assets — CSS/JS файлы модуля, если они есть.
- migrations — миграции для таблиц модуля.
Важно: не выносите логику в контроллеры. Если вы замечаете, что контроллер становится «толстым» — значит, пора вынести часть кода в отдельный класс. Например, в сервис.
// Пример сервиса в модуле blog
namespace app\modules\blog\components;
use app\modules\blog\models\Post;
class PostService
{
public function createPost($data)
{
$post = new Post();
$post->attributes = $data;
$post->author_id = \Yii::$app->user->id;
$post->save();
return $post;
}
}
Контроллер в этом случае будет тонким:
namespace app\modules\blog\controllers;
use app\modules\blog\components\PostService;
use yii\web\Controller;
class PostController extends Controller
{
public function actionCreate()
{
$service = new PostService();
$post = $service->createPost(\Yii::$app->request->post());
return $this->redirect(['view', 'id' => $post->id]);
}
}
Связываем модули между собой: без фанатизма
Модули не должны знать друг о друге. Но иногда им нужно взаимодействовать. Например, модуль «каталог» должен показывать цену товара, которую считает модуль «цены». Как быть?
Есть несколько способов:
- Через события. Один модуль генерирует событие, другой его слушает и реагирует.
- Через общий сервис. Выносите общую логику в отдельный компонент приложения, который доступен всем модулям.
- Через URL и API. Модули могут общаться через HTTP-запросы, если это уместно.
Я предпочитаю второй вариант. Создайте компонент, например, PriceManager, который будет доступен через Yii::$app->priceManager. Тогда любой модуль сможет получить цену, не зная деталей реализации.
// В конфигурации приложения
'components' => [
'priceManager' => [
'class' => 'common\components\PriceManager',
],
],
И в любом месте:
$price = Yii::$app->priceManager->getPrice($productId);
Это проще и надёжнее, чем создавать жёсткие зависимости между модулями.
Советы по масштабированию: как не выстрелить себе в ногу
Теперь, когда вы знаете базу, дам несколько практических советов, которые помогут вам расти без боли.
- Начинайте с модулей сразу. Не ждите, пока проект разрастётся. Создайте модуль для первой же функции, даже если она маленькая.
- Используйте миграции для каждого модуля. Храните миграции внутри модуля, чтобы при переносе модуля в другой проект таблицы создавались автоматически.
- Не злоупотребляйте вложенностью. Модуль внутри модуля — это редко бывает оправдано. Лучше создать отдельный модуль.
- Следите за зависимостями. Если модуль использует классы из другого модуля напрямую — это плохо. Старайтесь изолировать.
- Пишите тесты для модулей. Это спасёт вас при рефакторинге. Хотя бы минимальные.
Не бойтесь экспериментировать. Модульная структура — это не догма, а инструмент. Подстраивайте её под свой проект, и она будет работать на вас.
Что в итоге
Модульная структура в Yii2 — это не просто модный тренд, а реальный способ держать проект в порядке. Вы получаете изоляцию, переиспользуемость и лёгкость поддержки. Главное — начать с малого и не усложнять.
Если вы только начинаете — создайте один модуль для теста. Посмотрите, как он работает. Потом добавьте второй. Через пару недель вы не поймёте, как жили без этого.
Удачи в разработке, и пусть ваш код всегда остаётся чистым!
Студия WNDER



