Динамическое подключение модулей в Yii2
При разработке одной системы появилась необходимость подключать модули динамически без прописывания настроек в файле с конфигурацией приложения.
При разработке я использовал базовый шаблон приложения.
В папке components создадим файл ModuleManager.php для управления подключаемыми модулями.
Листинг файла ModuleManager.php:
<?php namespace app\components; use Yii; use yii\base\Component; use yii\base\BootstrapInterface; class ModuleManager extends Component implements BootstrapInterface { public function bootstrap($app) { Yii::$app->setModule('admin', [ 'class' => 'app\modules\admin\Admin' ]); Yii::$app->getModule('admin')->bootstrap(Yii::$app); Yii::$app->setModule('welcome', [ 'class' => 'app\modules\welcome\Welcome' ]); Yii::$app->getModule('welcome')->bootstrap(Yii::$app); } }
В выше указанном файле я подключаю модули вручную. Можно сделать подключение с использованием базы данных (оставляю на вашу фантазию).
Теперь приведу пример модуля admin. Он располагается в папке modules/admin.
Листинг файла Admin.php:
<?php namespace app\modules\admin; use app\components\ModuleInterface; /** * Class Admin Module * @package app\modules\admin */ class Admin extends \yii\base\Module implements ModuleInterface { /** * @var string the namespace that controller classes are in. */ public $controllerNamespace = 'app\modules\admin\controllers'; /** * Initializes the module. */ public function init() { parent::init(); } /** * Bootstrap method to be called during application bootstrap stage. * @param \app\components\Application $app */ public function bootstrap($app) { $app->getUrlManager()->addRules([ 'admin/test' => 'admin/default/test', ]); } }
Листинг файла ModuleInterface.php:
<?php namespace app\components; /** * Interface ModuleInterface * @package app\components */ interface ModuleInterface { /** * Initializes the module. */ public function init(); /** * Bootstrap method to be called during application bootstrap stage. * @param Application $app the application currently running */ public function bootstrap($app); }
Данный интерфейс будет использоваться во всех модулях. В функции bootstrap() мы описываем все правила для маршрутизации, если они нужны.
Теперь необходимо подключить класс ModuleManager в конфигурационном файле приложения (web.php).
$db = require(__DIR__ . '/db.php'); $config = [ ... 'bootstrap' => [ 'log', 'app\components\ModuleManager' ], ... ]; return $config;
Вот так все просто. В результате мы избавились от статичного подключения новых модулей в конфигурационном файле приложения.
Еще можно было бы хранить маршруты, например в файле Bootstrap, наследующего интерфейс BootstrapInterface. Однако, подключение все равно пришлось бы делать в конфиге приложения.
Теперь вы можете сделать любую реализацию подключения модулей в файле ModuleManager.php.
Будут вопросы, пишите.