Yii2-advanced: альтернативне розміщення папок для декількох додатків

Хочу поділитися альтернативним рецептом файлової структури для декількох додатків в Yii2-advanced, не вдаючись до модулів. Зовнішні відмінності, до яких ми прийдемо, виглядають наступним чином:

Кінцева файлова архітектура

Вступ
Я бачив на Хабре статтю, як різні оточення перетворити в модулі і покласти їх акуратно в межах проекту. Мені здається ідея, яку мені показав колега — набагато крутіше і зручніше!

  • Ідея така, що ми не пишемо в коді /site/site/index: ми пишемо /site/index!
  • Ми не мучимося з налаштуванням віртуальних хостів, сім-лінків і реврайтов: ми все кидаємо в один і той же файл!
  • Ми можемо мати на бюджетному хостингу (теоретично) будь-яка кількість доменів, сплативши опцію «1 сайт»!
Хіба це не круто?!

PS: Так, і до речі, до радості початківців: ви можете вирішити проблему «як зробити загальний upload для front&back».
PPS: Я розраховую, що ви вже встановили і випробували YII2 Advanced, і розумієте, навіщо вам саме цей варіант.

Цікаво? Тоді — вперед! Для прикладу беру останню, на поточний момент версії: 2.0.10.

Переходимо до рефакторінгу: перші кроки
  1. Якщо ви в передчутті революції на працюючому проекті, терміново тиснемо в папці свого проекту «tar -cf saveAndProtect.tar ./» Або, кажучи простіше: зробимо секс безпечним, шляхом бекапу останньої працюючої версії. У мене чиста версія всього з однієї вьюхой.

  2. Як бачили на скріншоті вище: потрібні нам програми (applications) складаємо в папку apps в корені проекту (так, її потрібно створити самому).

  3. докорінно створюємо папку web і перекидаємо в неї вміст свого фронт-енду (frontend). У папці backend видаляємо папку web: тепер вона спільна. Особисто ми тут зберігаємо лише статику з зображень і шрифтів. Стилі і JS так часто змінюються, що краще користуватися ассетами (assets).

  4. Тепер перенастройте свої домени на нову папку web, в корені проекту, і приступаємо до більш складним маніпуляціям.
Крок другий: трохи доопрацювати напилком (з)
  1. Правимо перші три инклуда (include) у index.php, де підключається autoload, Yii і common/ bootstrap: просто прибрати один рівень відповідно. Останній инклуд ми підключити поки не можемо, оскільки це вже bootstrap, яка відноситься до конкретного додатком з папки apps.

  2. Розрізняти програми, для старту будемо банально: $_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');
    

  3. Могли звернути увагу, що додався новий псевдонім(alias) @apps: це якраз наша нова папка. А константа YII_APP — конкретний додаток-папка, що необхідно підключити. Все прозоро! Виглядає — ну так, погоджуся: може злегка «топористо». Але саме те, що потрібно для швидкого старту.

  4. мерже (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')
    );
    

  5. Тепер пора визначити аліас @apps і поправити наші наявні. Це правиться в третьому підключається файл: common\config\bootstrap.php

    Додаємо аліас: Yii::setAlias('@apps', dirname(dirname(__DIR__)). '/apps');
    Наші програми правимо за принципом: Yii::setAlias('@console', Yii::getAlias('@apps'). '/console');.

  6. І останнє: залишилося налаштувати нашу console. Ви можете це зробити самі, із спортивного інтересу. А можете відкрити спойлер і отримати готове рішення:

    Налаштування консольної частини Yii2./yii.php
    #!/usr/bin/php env
    <?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(...);
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.