Додатки

Додатки це об’єкти, які керують всією структурою і життєвим циклом прикладної системи Yii. Кожна Yii прикладна система містить у собі один об’єкт додатка, який створюється у вхідному скрипті і глобально доступний через \Yii::$app.

Інформація: В залежності від контексту, коли ми говорим "додаток", це може означати як об’єкт додатка, так і прикладну систему додатка вцілому.

Існує два типи додатків: [[yii\web\Application|веб додатки]] та [[yii\console\Application|консольні додатки]]. Як можна здогадатися із назв, перший тип, в основному, займається обробкою веб запитів, а другий - консольними командами.

Конфігурації додатка

Коли вхідний скрипт створює додаток, він завантажить конфігурацію та застосує її до додатка, наприклад:

require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

// завантаження конфігурації додатка
$config = require(__DIR__ . '/../config/web.php');

// створення об’єкта додатка і його налаштування
(new yii\web\Application($config))->run();

Як і звичайні конфігурації, конфігурації додатка вказують як саме слід ініціювати властивості об’єктів додатка. Через те, що конфігурації додатків часто є складними, вони розбиваються на декілька конфігураційних файлів, наприклад, файл web.php у наведеному вище прикладі.

Властивості додатка

Існує багато важливих властивостей додатка, які ви налаштовуєте в конфігураціях додатка. Ці властивості, зазвичай, описують середовище, у якому працює додаток. Наприклад, додаток мусить знати яким чином завантажувати контролери, де зберігати тимчасові файли, і т.п. Нижче ми розглянемо дані властивості.

Об’язкові властивості

В кожному додатку, ви маєте налаштувати мінімум дві властивості: [[yii\base\Application::id|id]] та [[yii\base\Application::basePath|basePath]].

[[yii\base\Application::id|id]]

Властивість [[yii\base\Application::id|id]] є унікальним ID додатка, який відрізняє його від решти інших додатків. Здебільшого, це використовується всередені системи. Хоч і не є обов’язковим, але для кращої сумістності рекомендується використовувати буквено-цифрові символи при налаштуванні ID додатка.

[[yii\base\Application::basePath|basePath]]

Властивість [[yii\base\Application::basePath|basePath]] вказує на кореневу директорію додатка. Ця директорія, яка містить весь код прикладної системи додатка. В цій директорії, зазвичай, можуть знаходитись підкаталоги models, views, controllers, які містять код, що відповідає шаблону проектування MVC.

Ви можете налаштувати властивість [[yii\base\Application::basePath|basePath]], вказавши прямий шлях до директорії через псевдонім шляху. В обох випадках, вказана директорія має існувати, інакше буде отримано виняток. Шлях буде нормалізовано за допомогою виклику функції realpath().

Властивість [[yii\base\Application::basePath|basePath]] часто використовується для важливих шляхів (наприклад, шлях до runtime директорії). Саме з цієї причини, псевдонім шляху @app є зумовлений вказувати на дану директорію. Похідні шляхи потім можуть бути сформовані за допомогою цього псевдоніму шляху (наприклад, @app/runtime для звертання до runtime директорії).

Важливі властивості

Властивості, перелічені в даному підрозділі, частіш за все повинні бути визначені, тому що вони можуть відрізнятися у різних додатках.

[[yii\base\Application::aliases|aliases]]

Дана властивість дозволяє налаштувати вам безліч псевдонімів у рамках масиву. Ключами масива є імена псевдонімів, а значеннами - відповідні значення шляхів. Наприклад,

[
    'aliases' => [
        '@name1' => 'path/to/path1',
        '@name2' => 'path/to/path2',
    ],
]

Ця властивість доступна таким чином, аби ви змогли вказувати псевдоніми в рамках конфігурації додатка, а не викликаючи метод [[Yii::setAlias()]].

[[yii\base\Application::bootstrap|bootstrap]]

Дана властивість є дуже зручною, вона дозволяє вказувати масив компонентів, котрі мусять бути завантажені у процесі [[yii\base\Application::bootstrap()|початкового завантаження]] додатка. Наприклад, якщо ви хочете, щоб модуль виконував тонке налаштування URL правил, ви можете вказати його ID в якості елемента даної властивості.

Кожен із елементів даної властивості може вказуватись в одному із наступних форматів:

  • ID компонента додатка, що вказаний у компонентах.
  • ID модуля, що вказаний у модулях.
  • назва класа.
  • масив конфігурації.
  • анонімна функциія, яка створює та повертає об’єкт компонента.

Наприклад,

[
    'bootstrap' => [
        // ID компонента додатка або модуля
        'demo',

        // назва класа
        'app\components\Profiler',

        // масив конфігурації
        [
            'class' => 'app\components\Profiler',
            'level' => 3,
        ],

        // анонімна функція
        function () {
            return new app\components\Profiler();
        }
    ],
]

Інформація: Якщо ID модуля співпадає з ID компонента додатка, перевага буде віддана ініціалізації компонента додатка під час початкового завантаження. Якщо ж ви хочете використати модуль, вам потрібно використати анонімну функцію, як показано нижче: ```php [ function () { return Yii::$app->getModule('user'); }, ]



Під час початкового завантаження, буде створено кожний компонент. Якщо клас компонента реалізує інтерфейс 
[[yii\base\BootstrapInterface]], то буде викликаний його метод [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]].

Ще одним практичним прикладом є конфігурація [базового шаблону додатка](start-installation.md), у якій модулі
`debug` і `gii` визначені як компоненти початкового завантаження, коли додаток знаходиться режимі розробки.

```php
if (YII_ENV_DEV) {
    // налаштування конфігурації для середовища 'dev'
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = 'yii\debug\Module';

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = 'yii\gii\Module';
}

Примітка: Якщо вказувати велику кількість компонентів у bootstrap - це негативно позначиться на продуктивності додатка, оскільки для кожного запиту буде виконуватись один й той самий набір компонентів. Таким чином, потрібно розсудливо використовувати компоненти початкового завантаження.

[[yii\web\Application::catchAll|catchAll]]

Дана властивість підтримується тільки [[yii\web\Application|веб додатками]]. Вона вказує на дії контролера, які мусять обробляти всі вхідні запити від користувача. Переважно, це використовується, коли додаток знаходиться в режимі обслуговування і повинен обробити всі запити через одну дію.

Конфігурація є масивом, перший елемент якого вказує на маршрут події. Решта елементів масиву у форматі ключ-значення вказують на додаткові параметри, які мають бути передані події. Наприклад,

[
    'catchAll' => [
        'offline/notice',
        'param1' => 'value1',
        'param2' => 'value2',
    ],
]

[[yii\base\Application::components|components]]

Дана властивість є найважливішою. Вона дозволяє вам зареєструвати іменні компоненти у компонентах додатку, які ви можете використовувати в інших місцях. Наприклад,

[
    'components' => [
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
    ],
]

Кожен компонент додатка вказаний масивом у форматі ключ-значення. Ключ являє собою ID компонента додатка, у той час як значення являє собою назву класа або конфігурацію.

Ви можете зареєструвати будь-який компонент у додатку, який потім буде доступний глобально за допомогою виразу \Yii::$app->componentID.

Більш детальна інформація наведена в розділі Компоненти додатка.

[[yii\base\Application::controllerMap|controllerMap]]

Дана властивість дозволяє вам встановлювати відповідність між ID контролера та його класом. За замовчуванням, Yii встановлює відповідність між ID контролера та його класом згідно домовленості (таким чином, ID post буде відповідати app\controllers\PostController). За допомогою налаштування даної властивості ви можете змінити домовленість для необхідних контролерів. У наведеному прикладі, account буде відповідати app\controllers\UserController, в той час, як article буде відповідати app\controllers\PostController.

[
    'controllerMap' => [
        [
            'account' => 'app\controllers\UserController',
            'article' => [
                'class' => 'app\controllers\PostController',
                'enableCsrfValidation' => false,
            ],
        ],
    ],
]

Ключами масиву даної властивості є ID контролерів, а значеннями є назви класів контролерів або конфігурації.

[[yii\base\Application::controllerNamespace|controllerNamespace]]

Дана властивість вказує на простір імен за замовчуванням, під яким повинні знаходитись класи контролерів. За замовчуванням, це значення рівне app\controllers. Якщо ID контролера є post, то, згідно домовленості, відповідна назва класу контролера (без простору імен) буде PostController, а повна назва класу буде app\controllers\PostController.

Класи контролерів можуть також знаходитись у підкаталогах директорії, що відповідає її простору імені. Наприклад, ID контролера admin/post відповідає повне ім’я класа контролера app\controllers\admin\PostController.

Дуже важливо, щоб повне ім’я класа контролера могло бути використане автозавантаженням і фактичний простір імен вашого контролера відповідав цій властивості. В іншому випадку, ви отримаєте помилку із заголовком "Сторінка не знайдена", коли спробуєте отримати доступ до додатка.

У випадку, якщо ви хочете змінити домовленість, яку розглянуто вище, ви можете використовувати властивість controllerMap.

[[yii\base\Application::language|language]]

Дана властивість вказує на мову додатка, на якій додаток повинен відображати зміст кінцевому користувачу. За замовчуванням, значення даної властивості рівне en, означаючи англійську мову. Якщо ваш додаток підтримує декілька мов, ви необхідно налаштувати дану властивість.

Значення даної властивості визначає кілька різних аспектів інтернаціоналізації, в тому числі переклади повідомлень, форматування дат, форматування чисел, і т. п. Наприклад, віджет [[yii\jui\DatePicker]] використовує дану властивість для визначення мови за замовчуванням, на якій має бути зображений календар і формат даних для календаря.

Рекомендується вказувати мову у рамках стандатру IETF. Наприклад, для англійської мови використовується en, в той час як для англійської в США - en-US.

Більш детальна інформація наведена у розділі Інтернаціоналізація.

[[yii\base\Application::modules|modules]]

Дана властивість визначає модулі, які містить додаток.

Значенням властивості є масив імен класів модулів або конфігурацій, а ключами цього масиву виступають ID модулів. Наприклад,

[
    'modules' => [
        // модуль "booking" визначено класом модуля
        'booking' => 'app\modules\booking\BookingModule',

        // модуль "comment" визначено масивом конфігурації
        'comment' => [
            'class' => 'app\modules\comment\CommentModule',
            'db' => 'db',
        ],
    ],
]

Більш детальна інформація наведена у розділі Модулі.

[[yii\base\Application::name|name]]

Дана властивість вказує на ім’я додатка, яке може бути відображене кінцевому користувачу. На відміну від властивості [[yii\base\Application::id|id]], яка має бути унікальною, значення даної властивості потрібне в основному для відображення і не є обов’язково є унікальною.

Якщо ваш код не використовує дану властивість, то ви можете не налаштовувати її.

[[yii\base\Application::params|params]]

Дана властивість описує масив глобально доступних параметрів додатка. Замість того, щоб використовувати жорстко фіксовані числа і строки у вашому коді, краще оголосити їх параметрами додатка в одному місці і використовувати в необхідних місцях коду. Наприклад, ви можете визначити розмір прев’ю-зображень для зображеннь наступним чином:

[
    'params' => [
        'thumbnail.size' => [128, 128],
    ],
]

Потім, коли вам потрібно використати дані значення у вашому коді, ви можете зробити це наступним чином:

$size = \Yii::$app->params['thumbnail.size'];
$width = \Yii::$app->params['thumbnail.size'][0];

Якщо пізніше вам знадобиться змінити розмір прев’ю зображення, то вам потрібно буде змінити це значення лише у конфігураційному файлі додатка, не змінюючи будь-який залежний код.

[[yii\base\Application::sourceLanguage|sourceLanguage]]

Дана властивість вказує мову, на якій написаний код додатка. За замовчуванням значення рівне 'en-US', що означає англійську мову (США). Ви повинні змінити дану властивість, якщо мовою змісту у вашому коді є не англійська мова.

Аналогічно властивості language, ви повинні вказати дану властивість у рамках стандарту IETF. Наприклад, для англійської мови використовується en, в той час як для англійської в США - en-US.

Більш детальна інформація наведена у розділі Інтернаціоналізація.

[[yii\base\Application::timeZone|timeZone]]

Дана властивість надає альтернативний спосіб встановлення часової зони за замовчуванням у процесі роботи додатка. Таким чином, вказуючи дану властивість, ви, по суті, викликаєте PHP функцію date_default_timezone_set(). Наприклад,

[
    // 'Europe/Kiev' для України
    'timeZone' => 'America/Los_Angeles',
]

[[yii\base\Application::version|version]]

Дана властивість вказує на версію додатка. За замовчуванням значення рівне '1.0'. Ви можете не змінювати дану властивість, якщо ваш код не використовує її.

Корисні властивості

Властивості, які перераховані в даному розділі, не є часто змінюваними, так як їх значення за замовчуванням відповідають загальноприйнятим домовленостям. Однак, ви можете їх налаштувати, якщо вам потрібно використовувати інші значення.

[[yii\base\Application::charset|charset]]

Властивість вказує кодування, яке використовує додаток. За замовчуванням значення рівне 'UTF-8', яке має бути незмінним для більшості додатків, тільки якщо ви не працюєте із застарілим кодом, який використовує значний об’єм не юнікод даних.

[[yii\base\Application::defaultRoute|defaultRoute]]

Властивість вказує маршрут, який повинен використовувати додаток, коли його не вказано у вхідному запиті. Маршрут може складатись із ID модуля, ID контролера і/або ID дії. Наприклад, help, post/create, admin/post/create. Якщо дію не вказано, то буде використано значення за замовчуванням, що вказане у [[yii\base\Controller::defaultAction]].

Для [yii\web\Application|веб додатків] значення за замовчуванням даної властивості рівне 'site', що означає контролер SiteController і його дія за замовчуванням. Таким чином, якщо ви спробуєте отримати доступ до додатка, не вказавши маршрут - буде відображено результат дії app\controllers\SiteController::actionIndex().

Для [yii\console\Application|консольних додатків] значення за замовчуванням рівне 'help', яке означає, що повинна використовуватись вбудована команда [[yii\console\controllers\HelpController::actionIndex()]]. Таким чином, якщо ви виконаєте команду yii без аргументів, вам будет зображена довідкова інформація.

[[yii\base\Application::extensions|extensions]]

Дана властивість описує перелік розширень, які встановлені і використовуються додатком. За замовчуванням, значенням даної властивості буде масив, отриманий із файла @vendor/yiisoft/extensions.php. Файл extensions.php генерується і підтримується автоматично, коли ви використовуєте Composer для встановлення розширень. Таким чином, у більшості випадків, вам не потрібно налаштовувати дану властивість.

В особливих випадках, коли ви хочете керувати розширеннями власноруч, ви можете вказати дану властивість наступним чином:

[
    'extensions' => [
        [
            'name' => 'extension name',
            'version' => 'version number',
            'bootstrap' => 'BootstrapClassName',  // опціонально, може бути також масив конфігурації
            'alias' => [  // опціонально
                '@alias1' => 'to/path1',
                '@alias2' => 'to/path2',
            ],
        ],

        // ... аналогічно для решти розширень ...

    ],
]

Як бачите, властивість є масивом специфікацій розширень. Кожне розширення вказано масивом, який складається з елементів name і version. Якщо розширення має бути виконано в процесі початкового завантаження, то слід вказати елемент у bootstrap властивості, який може бути іменем класа або масивом конфігурації. Розширення також може визначати декілька псевдонімів.

[[yii\base\Application::layout|layout]]

Дана властивість визначає ім’я шаблону за замовчуванням, який мусить бути використаний при формувані представлення. Значення за замовчуванням рівне 'main', яке означає, що має бути використаний шаблон main.php в директорії шаблонів. Якщо обидві властивості, директорія шаблонів та директорія представлень, приймають значення за замовчуванням, то файл шаблону за замовчуванням може бути представлений псевдонімом шляху як @app/views/layouts/main.php.

Для відключення використання шаблону, ви можете вказати дану властивість як false, однак це є дуже рідкісним випадком.

[[yii\base\Application::layoutPath|layoutPath]]

Дана властивість визначає шлях, по якому слід шукати шаблони. Значення за замовчуванням рівне layouts, що означає підпапку у директорії представлень. Якщо значення директорії представлень є значенням за замовчуванням, то директорія шаблонів за замовчуванням може бути представлена псевдонімом шляху як @app/views/layouts.

Ви можете налаштувати дану властивість як директорію, так і як псевдонім шляху.

[[yii\base\Application::runtimePath|runtimePath]]

Дана властивість визначає шлях, по якому зберігаються тимчасові файли, такі як: лог файли, кеш файли. За замовчуванням це значення рівне директорії, яка преставлена псевдонімом шляху @app/runtime.

Ви можете налаштувати дану властивість як директорію або як псевдонім шляху. Зверніть увагу, що дана директорія має бути доступна для запису процесом, який виконує додаток. Також директорія має бути захищена від доступу кінцевим користувачам, оскільки файли, які зберігаються в ній,, можуть містити важливу інформацію.

Для спрощення роботи з даною директорією, Yii надає зумовлений псевдонім шляху @runtime.

[[yii\base\Application::viewPath|viewPath]]

Дана властивість визначає базову директорію, де містяться всі файли представлень. Значення за замовчуванням являє собою псевдонім @app/views. Ви можете налаштувати дану властивість як директорі або псевдонім шляху.

[[yii\base\Application::vendorPath|vendorPath]]

Дана властивість визначає директорію сторонніх бібліотек, які використовуються і керуються за допомогою Composer. Вона містить всі сторонні бібліотеки, які використовуються додатком, включаючи сам Yii фреймворк. Значеня за замовчуванням являє собою псевдонім @app/vendor.

Ви можете налаштувати дану властивість як директорію або псевдонім шляху. При зміні даної властивості, переконайтесь, що ви також змінили відповідним чином налаштування Composer.

Для спрощення роботи з даною директорією, Yii надає зумовлений псевдонім шляху @vendor.

[[yii\console\Application::enableCoreCommands|enableCoreCommands]]

Дана властивість підтримується тільки [[yii\console\Application|консольними додатками]]. Вона вказує чи потрібно використовувати вбудовані в Yii консольні команди. Значення за замовчуванням рівне true.

Події додатка

Додаток викликає декілька подій під час свого життєвого циклу обробки запиту. Ви можете приєднати обробники подій в конфігурації додатка наступним чином:

[
    'on beforeRequest' => function ($event) {
        // ...
    },
]

Використання синтаксису on eventName детально описано у розділі Конфігурації.

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

\Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
    // ...
});

[[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]]

Дана подія виникає до того, як додаток починає обробляти вхідний запит. Справжнє ім’я події - beforeRequest.

Коли виникає ця подія, об’єкт додатка вже створений і проініційований. Таким чином, це є коректним місцем для додавання вашого коду за допомогою подій для перехвату управління обробки запиту. Наприклад,в обробник події ви може динамічно призначати мову додатка [[yii\base\Application::language]] в залежності від деяких параметрів.

[[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]]

Дана подія виникає після закінчення обробки запиту додатком, але до відправки відповіді. Справжнє ім’я події - afterRequest.

На момент виникнення даної події, обробка запиту завершена і ви можете використати це для побудови постобробки запиту, з метою налаштування відповіді.

Зверніть увагу, що у компоненті [[yii\web\Response|response]] також виникають події в процесі відправки даних кінцевому користувачу. Ці події виникають після поточної події.

[[yii\base\Application::EVENT_BEFORE_ACTION|EVENT_BEFORE_ACTION]]

Подія виникає до виконання кожної дії контролера. Справжнє ім’я події - beforeAction.

Параметр події є об’єктом [[yii\base\ActionEvent]]. Обробник події може встановлювати властивість [[yii\base\ActionEvent::isValid]] рівним false для зупинки виконання дії.

Наприклад,

[
    'on beforeAction' => function ($event) {
        if (деяка умова) {
            $event->isValid = false;
        } else {
        }
    },
]

Зверніть увагу на те, що така ж подія beforeAction виникає також у модулях та контролерах. Об’єкти додатку є першими, хто ініціює дані події, за якими ініціюють модулі (якщо такі є), і в кінці - контролери. Якщо обробник події встановлює властивість [[yii\base\ActionEvent::isValid]] рівним false, то всі наступні події не будуть викликані.

[[yii\base\Application::EVENT_AFTER_ACTION|EVENT_AFTER_ACTION]]

Ця подія виникає після виконання дії контролера. Справжнє ім’я події - afterAction.

Параметр події є об’єктом [[yii\base\ActionEvent]]. Через властивість [[yii\base\ActionEvent::result]] обробник події може отримати доступ або змінити результат дії контролера. Наприклад,

[
    'on afterAction' => function ($event) {
        if (деяка умова) {
            // modify $event->result
        } else {
        }
    },
]

Зверніть увагу на те, що така ж подія afterAction виникає також у модулях та контролерах. Ці об’єкти ініціюють події у зворотньому порядку, порівнюючи із beforeAction. Таким чином, контролери є першими, хто ініціює дану подію, далі йдуть модулі (якщо такі є), і врешті - у додатках.

Життєвий цикл додатка

Життєвий цикл додатка

Коли вхідний скрипт виконується для обробки запиту, додаток пройде наступний життєвий цикл:

  1. Вхідний скрипт завантажує конфігурацію додатка у якості масива.
  2. Вхідний скрипт створює новий об’єкт додатка:
  3. Викликається метод [[yii\base\Application::preInit()|preInit()]], який налаштовує деякі життєво важливі властивості додатка, як наприклад [[yii\base\Application::basePath|basePath]].
  4. Реєструється [[yii\base\Application::errorHandler|обробник помилок]].
  5. Налаштовуються властивості додатку.
  6. Викликається метод [[yii\base\Application::init()|init()]], який далі викликає метод [[yii\base\Application::bootstrap()|bootstrap()]] для початкового завантаження компонентів.
  7. Вхідний скрипт викликає метод [[yii\base\Application::run()]] для запуску додатка:
  8. Ініціюється подія [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]].
  9. Обробка запиту: розбір інформації запиту на маршрут та відповідні параметри; створення об’єктів модуля, контролера та дії, згідно вказаного маршруту; ініціювання подій.
  10. Ініціюється подія [[yii\base\Application::EVENT_AFTER_REQUEST|EVENT_AFTER_REQUEST]].
  11. Відповідь надсилається кінцевому користувачу.
  12. Вхідний скрипт отримує значення статусу виходу із додатка та завершує обробку запиту.