[Из песочницы] Yii2-advanced: альтернативное размещение папок для нескольких приложений
Вступление
Я видел на Хабре статью, как разные окружения превратить в модули и сложить их аккуратно внутри проекта. Мне кажется идея, которую мне показал коллега — намного круче и удобнее!
- Идея такова, что мы не пишем в коде /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 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 (…);
Комментарии (12)
6 декабря 2016 в 18:00 (комментарий был изменён)
0↑
↓
Не надо изобретать велосипед, и учить этому других.Если вам нужны несколько сайтов, зависимых друг от друга (допустим, admin.example.com, crm.example.com, mail.example.com, etc), то делаете каждый подсайт в виде модуля и указываете роутинг с нужного домена в конфиге (см. http://nickbartlett.com/yii-multisite-point-domain-to-modules/). При этом, webroot с каждого домена идет на одну и ту же папку.
Если же сайты не должны быть зависимы друг от друга, то вообще в разные проекты нужно разделять всё.
6 декабря 2016 в 18:11
0↑
↓
Вы совершенно верно мыслите, с точки зрения человека, которому доступен личный сервер.
Но, находясь на урезанном хостинге и с желанием экономии — будет слегка напряжно реализовать все красиво.
На счет модулей — я сразу оговорил, что предлагаю вариант без оных. Также есть отзыв пришедшего программиста в нашу команду, который сказал: «О, так понятнее и проще, чем на модулях»
А сайты… В нашем случае это можно сравнить с фрилансом. Когда есть сторона работодателя и соискателя. У которых пересекаются модели, методы, данные, компоненты и т.д.Велосипед буду изобретать, т.к. только так делаются какие-то прорывы из консерватизма.
Чтоб учить, необходимо сказать: «делайте так». Я лишь предложил альтернативу, которую внедрили в моем проекте, и которая лично мне приглянулась.
Девяти добавлениям в избранное, видимо, также.Спасибо за отзыв. Я не претендую на прорыв в технологиях. Буду рад, если кому данный подход также понравится больше, чем модульность или у кого нет желания вкладываться в хостинг.
6 декабря 2016 в 21:42
0↑
↓
чем плох этот вариант https://github.com/mickgeek/yii2-advanced-one-domain-config?6 декабря 2016 в 21:58
0↑
↓
Если вы имели в виду, «как мне это решение», то если я верно понял — то интересное решение. Более быстрая настройка и неизменная структура файлов
Из плюсов моего варианта — более удобно, если, ни дай бог, два или более приложений должны иметь общие ресурсы: картинки, шрифты.Я выше отметил, что у нас сильно было завязано на 2 приложения. У них было много общего. Т.е. как предлагали — можно было сделать через модули. Попробовали сделать так — лично нам понравилось. Штатный вариант теперь чет не нравится)
6 декабря 2016 в 21:59
0↑
↓
Это только Yii под backend и frontend понимает админку и часть для обычных пользователей соответственно?
Или это общепринято? :)Я чет всю жизнь под первым понимал сервер-сайд, под вторым — отдача html + статики. :)
С учетом общих файлов статики, данное решение более удобно применять для поддоменов. :)
Хотя можно статику разнести по папкам доменов, а php натравить на:
а) общий файл;
б) разные файлы, но иметь предложенную структуру папок.6 декабря 2016 в 22:07
0↑
↓
Ну второй идет в двух вариантах: advanced с такой структурой и basic. Там по другомуА текущее решение — не обязательно применять))) Его еще можно перекроить 10 раз. Мне, до написания этой статьи, просто было немного не понятно как этот Yii «склеивается». Попутно разобрался и избавился от мандража, что перекроить Yii — это страшно)
6 декабря 2016 в 22:38
0↑
↓
Тут стоит понимать что
yii2-app-advanced
иyii2-app-basic
— это не окончательные варианты структуры проектов. Это шаблоны от команды фреймворка, как можно организовать структуру на одну и на несколько точек входа. Кому подходит, тот пользуется готовым. Кому нет — делает свой шаблон.Вы даже можете оформить свой вариант в виде пакета для composer, чтобы начинать новые проекты по этому шаблону с команды:
composer create-project --prefer-dist username/yii2-app-cool .
7 декабря 2016 в 07:07
0↑
↓
Термины «backend» и «frontend» имеют значение в зависимости от контекста. Это может быть админка/сайт, сервер/браузер, apache/nginx и т.д. Это просто обозначение 2 сторон канала передачи информации.7 декабря 2016 в 08:58
0↑
↓
Это только Yii под backend и frontend понимает админку и часть для обычных пользователей соответственно?
Или это общепринято? :)
Это очень давно было так принято, во времена, когда на JS не писали приложения, и отдельно JS-разработчики не нанимались.
Бэкендом называлась админка, фронтендом — пользовательская часть.
7 декабря 2016 в 08:35
0↑
↓
Интересное решение. Попробуйте на github опубликовать ;)
Лично я склоняюсь больше к использованию Yii-basic и модульности. Поскольку кажется, что yii advanced склоняет мешать логику в разных частях приложения, делая проект тем самым более запутанным. Лучше делать несколько проектов со своими направлениями, чем один с разными приложениями.7 декабря 2016 в 08:39 (комментарий был изменён)
0↑
↓
Интересное решение. Попробуйте на github опубликовать ;)
Спасибо. Да там выше предложена ссылка, где эта задача решается на уровне одного только веб-сервера с помощью реврайтов. Можно сказать, что моя «миссия» уже выполнена другим человеком))))
7 декабря 2016 в 09:26
0↑
↓
Если подходит вариант с поддиректорией («mysite.com/» и «mysite.com/admin»), то тут есть хорошее решение. Переносим папку «backend/web» в «frontend/web/admin» и корректируем пути в «admin/index.php».