Хочу поделиться альтернативным рецептом файловой структуры для нескольких приложений в Yii2-advanced, не прибегая к модулям. Внешние отличия, к которым мы придем, выглядят следующим образом:
Я видел на Хабре статью, как разные окружения превратить в модули и сложить их аккуратно внутри проекта. Мне кажется идея, которую мне показал коллега — намного круче и удобнее!
Разве это не круто?!
PS: Да, и кстати, к радости начинающих: вы можете решить проблему «как сделать общий upload для front&back».
PPS: Я рассчитываю, что вы уже установили и опробовали YII2 Advanced, и понимаете, зачем вам именно этот вариант.
Интересно? Тогда — вперед! Для примера беру последнюю, на текущий момент версию: 2.0.10.
Все!
Довольно простыми манипуляциями для человека немного поработавшего с YII2 мы получили структурированный по приложениям проект, который откликается на любое количество доменов и удобен на бюджетных хостингах, когда у нас есть лишь 1 каталог. Либо манипуляции с каталогами и сим-линками вызывает определенные проблемы.
Рассчитываю, что мой труд оказался вам интересен. В конце лишь добавлю возможные вопросы, которые могут возникнуть в этой непривычной архитектуре.
В: У меня, на шаге Х просто белый экран!
О: Вы допустили опечатку до инициализации Yii. Временно добавьте в самое начало index.php строку: ini_set(«display_errors»,«1»); ini_set(«error_reporting», E_ALL);
В: Скомпиленные Ассеты могут смешаться?
О: Вряд ли. Почти за год работы проекта не отмечено ни одного случая
В: Robots и favico не для каждого домена, а смешаны в кучу?
О: Всегда можно разрулить реврайтами апача по RewriteCond %{HTTP_HOST}
В: А как можно получить ссылку из другого приложения? На примере «модулей», это было бы элементарно.
О: Создайте дополнительную компоненту и Yii::$app->urlManagerFrontend->createUrl(...);
Вступление
Я видел на Хабре статью, как разные окружения превратить в модули и сложить их аккуратно внутри проекта. Мне кажется идея, которую мне показал коллега — намного круче и удобнее!
- Идея такова, что мы не пишем в коде /site/site/index: мы пишем /site/index!
- Мы не мучаемся с настройкой виртуальных хостов, сим-линков и реврайтов: мы все кидаем в один и тот же файл!
- Мы можем иметь на бюджетном хостинге (теоретически) любое количество доменов, оплатив опцию «1 сайт»!
Разве это не круто?!
PS: Да, и кстати, к радости начинающих: вы можете решить проблему «как сделать общий upload для front&back».
PPS: Я рассчитываю, что вы уже установили и опробовали YII2 Advanced, и понимаете, зачем вам именно этот вариант.
Интересно? Тогда — вперед! Для примера беру последнюю, на текущий момент версию: 2.0.10.
Переходим к рефакторингу: первые шаги
- Если вы в предвкушении революции на работающем проекте, срочно жмем в папке своего проекта «tar -cf saveAndProtect.tar ./» Или выражаясь проще: предохраняемся, путем бекапа последней работающей версии. У меня чистая версия всего с одной вьюхой.
- Как видели на скриншоте выше: нужные нам приложения (applications) складываем в папку apps в корне проекта (да, ее нужно создать самому).
- В корне создаем папку web и перекидываем в нее содержимое своего фронт-энда (frontend). В папке backend удаляем папку web: теперь она общая. Лично мы тут храним лишь статику из картинок и шрифтов. Стили и JS так часто меняются, что лучше пользоваться ассетами (assets).
- Теперь перенастройте свои домены на новую папку web, в корне проекта, и приступаем к более сложным манипуляциям.
Шаг второй: немного доработать напильником (с)
- Правим первые три инклуда (include) в index.php, где подключается autoload, Yii и common/ bootstrap: просто убрать один уровень соответственно. Последний инклуд мы подключить пока не можем, т.к. это уже bootstrap, который относится к конкретному приложению из папки apps.
- Различать приложения, для старта будем банально: $_SERVER['HTTP_HOST']. Пишем switch-case и заменяем этим кодом последний инклуд и на этом с index.php мы закончили. Должно получится так:
// определяем запрошенный APP switch ($_SERVER['HTTP_HOST']) { case 'frontend.dev': case 'site.ru': define('YII_APP', 'frontend'); break; case 'backend.dev': case 'admin.site.ru': define('YII_APP', 'backend'); break; default: // лично у меня тут 301й редирект на главную exit("domain not defined"); } // определяем папку приложения и подключаем его конфиг define('YII_APP_DIR', Yii::getAlias('@apps') . '/' . YII_APP); require(YII_APP_DIR . '/config/bootstrap.php');
- Могли обратить внимание, что добавился новый алиас(alias) @apps: это как раз наша новая папка. А константа YII_APP — конкретное приложение-папка, что необходимо подключить. Все прозрачно! Выглядит — ну да, соглашусь: может слегка «топористо». Но именно то, что нужно для быстрого старта.
- В мерже (merge) конфига у нас остались старые пути. В одном случае понижаем инклуд на уровень, во втором — используем нашу новую константу:
$config = yii\helpers\ArrayHelper::merge( require(__DIR__ . '/../common/config/main.php'), require(__DIR__ . '/../common/config/main-local.php'), require(YII_APP_DIR . '/config/main.php'), require(YII_APP_DIR . '/config/main-local.php') );
- Теперь пора определить алиас @apps и поправить наши имеющиеся. Это правится в третьем подключаемом файле: common\config\bootstrap.php
Добавляем алиас: Yii::setAlias('@apps', dirname(dirname(__DIR__)). '/apps');
Наши приложения правим по принципу: Yii::setAlias('@console', Yii::getAlias('@apps'). '/console');.
- И последнее: осталось настроить нашу console. Вы можете это сделать сами, из спортивного интереса. А можете открыть спойлер и получить готовое решение:
Настройка консольной части Yii2./yii.php
#!/usr/bin/env php <?php defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); define('YII_APP', 'console'); require(__DIR__ . '/vendor/autoload.php'); require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php'); require(__DIR__ . '/common/config/bootstrap.php'); require(__DIR__ . '/apps/console/config/bootstrap.php'); $config = yii\helpers\ArrayHelper::merge( require(__DIR__ . '/common/config/main.php'), require(__DIR__ . '/common/config/main-local.php'), require(__DIR__ . '/apps/console/config/main.php'), require(__DIR__ . '/apps/console/config/main-local.php') ); $application = new yii\console\Application($config); $exitCode = $application->run(); exit($exitCode);
apps\console\config\main.php правим участок с merge
$params = array_merge( require(__DIR__ . '/../../../common/config/params.php'), require(__DIR__ . '/../../../common/config/params-local.php'), require(__DIR__ . '/params.php'), require(__DIR__ . '/params-local.php') );
Все!
Резюме
Довольно простыми манипуляциями для человека немного поработавшего с YII2 мы получили структурированный по приложениям проект, который откликается на любое количество доменов и удобен на бюджетных хостингах, когда у нас есть лишь 1 каталог. Либо манипуляции с каталогами и сим-линками вызывает определенные проблемы.
Рассчитываю, что мой труд оказался вам интересен. В конце лишь добавлю возможные вопросы, которые могут возникнуть в этой непривычной архитектуре.
В: У меня, на шаге Х просто белый экран!
О: Вы допустили опечатку до инициализации Yii. Временно добавьте в самое начало index.php строку: ini_set(«display_errors»,«1»); ini_set(«error_reporting», E_ALL);
В: Скомпиленные Ассеты могут смешаться?
О: Вряд ли. Почти за год работы проекта не отмечено ни одного случая
В: Robots и favico не для каждого домена, а смешаны в кучу?
О: Всегда можно разрулить реврайтами апача по RewriteCond %{HTTP_HOST}
В: А как можно получить ссылку из другого приложения? На примере «модулей», это было бы элементарно.
О: Создайте дополнительную компоненту и Yii::$app->urlManagerFrontend->createUrl(...);