2 · курс
0%
Главная/🏗Структура приложения

04Приложение и его компоненты

Из чего состоит приложение Yii, что делает входной скрипт, какие свойства приложения стоит настроить и как работают компоненты через Yii::$app.

⏱ ~7 мин 📚 4 главы руководства

Приложение Yii — это объект Yii::$app, созданный входным скриптом по массиву-конфигурации. Он держит компоненты (БД, запрос, ответ, пользователь…), знает, где лежат контроллеры и представления, и проводит каждый запрос через свой жизненный цикл.

Что есть в приложении кроме MVC#

Входной скрипт

единственный PHP-файл, доступный снаружи (web/index.php или консольный yii). Создаёт приложение и запускает обработку запроса.

Приложение

глобальный объект, координирующий всё остальное; доступен как Yii::$app.

Компоненты приложения

именованные сервисы (db, request, user, cache…), зарегистрированные в конфигурации и создаваемые лениво.

Модули

самодостаточные мини-приложения со своими контроллерами, моделями и представлениями. См. Модули.

Фильтры

код до и после действия контроллера: доступ, кеш, CORS. См. Фильтры.

Виджеты

переиспользуемые блоки интерфейса внутри представлений. См. Виджеты.

Входной скрипт#

Он делает пять вещей: объявляет константы, подключает автозагрузчик Composer и класс Yii, читает конфигурацию, создаёт приложение и вызывает run().

PHP
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require __DIR__ . '/../vendor/autoload.php';          // автозагрузчик Composer
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';  // класс Yii + автозагрузчик Yii + DI-контейнер

$config = require __DIR__ . '/../config/web.php';

(new yii\web\Application($config))->run();
PHP
#!/usr/bin/env php
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);

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

$config = require __DIR__ . '/config/console.php';

$exitCode = (new yii\console\Application($config))->run();
exit($exitCode);

Константы объявляют в самом начале, до подключения других файлов:

YII_DEBUG
отладочный режим: подробные ошибки со стеком, больше логов. По умолчанию false
YII_ENV
окружение: prod (по умолчанию), dev, test; порождает YII_ENV_PROD, YII_ENV_DEV, YII_ENV_TEST
YII_ENABLE_ERROR_HANDLER
включать ли обработчик ошибок Yii. По умолчанию true

defined('X') or define('X', v) — идиома «определить, если ещё не определено»: так константу можно переопределить снаружи, например в тестовом входном скрипте.

Объект приложения#

Два вида: yii\web\Application для HTTP и yii\console\Application для команд. Оба наследуют yii\base\Application, которая в свою очередь — модуль и Service Locator.

Обязательные свойства#

config/web.phpPHP
return [
    'id' => 'basic',                    // уникальный идентификатор приложения
    'basePath' => dirname(__DIR__),     // корень с кодом; задаёт псевдоним @app
    // ...
];

Свойства, которые настраивают чаще всего#

aliases
массив псевдонимов путей: ['@uploads' => '@webroot/uploads']. Удобнее, чем Yii::setAlias() в коде
bootstrap
что создать при старте каждого запроса: ID компонентов/модулей, классы, конфиги, замыкания. Компонент с BootstrapInterface получит вызов bootstrap($app). Держите список коротким — он выполняется всегда
components
главное свойство: регистрация компонентов приложения (см. ниже)
controllerMap
явное соответствие ID контроллера → класс, когда соглашение об именах не подходит
controllerNamespace
пространство имён контроллеров, по умолчанию app\controllers; admin/post ищется в app\controllers\admin\PostController
modules
подключённые модули: 'forum' => ['class' => 'app\modules\forum\Module']
params
глобальные параметры: Yii::$app->params['adminEmail']. Обычно подключают config/params.php
language / sourceLanguage
язык интерфейса (ru-RU) и язык исходного кода (en-US по умолчанию); см. i18n
timeZone
часовой пояс приложения, по сути date_default_timezone_set()
catchAll
только web: маршрут, обрабатывающий все запросы (режим обслуживания): ['site/offline', 'param' => 'value']
name, version, charset
название для показа пользователям, версия, кодировка (UTF-8)

Свойства с разумными умолчаниями#

defaultRoute
маршрут без явного указания: site для web (→ site/index), help для консоли
layout, layoutPath, viewPath
шаблон по умолчанию main в @app/views/layouts, представления в @app/views. layout => false отключает шаблон
runtimePath
временные файлы (логи, кеш): @app/runtime, псевдоним @runtime. Должна быть доступна на запись и закрыта от веба
vendorPath
пакеты Composer: @app/vendor, псевдоним @vendor
extensions
список установленных расширений; Composer сам генерирует @vendor/yiisoft/extensions.php
enableCoreCommands
консоль: включать ли встроенные команды (migrate, cache, asset…). По умолчанию true

События приложения#

Обработчики вешают прямо в конфигурации через синтаксис 'on имяСобытия' или кодом после создания приложения:

PHP
return [
    'on beforeRequest' => function ($event) {
        // приложение создано, запрос ещё не обрабатывался — удобно выбрать язык по домену
    },
    'on beforeAction' => function (\yii\base\ActionEvent $event) {
        if ($somethingWrong) {
            $event->isValid = false;   // отменить выполнение действия
        }
    },
    'on afterAction' => function (\yii\base\ActionEvent $event) {
        $event->result = strtoupper($event->result);   // изменить результат действия
    },
];
Событие Когда Полезно для
beforeRequestдо начала обработки запросапереключение языка, темы, редиректы на обслуживание
afterRequestпосле обработки, до отправки ответапостобработка, статистика
beforeActionперед действием; сначала у приложения, затем у модуля, затем у контроллерапроверки доступа «на самом верху»
afterActionпосле действия; в обратном порядке: контроллер → модуль → приложениеобёртка результата

Жизненный цикл приложения#

  1. Входной скрипт читает конфигурацию — обычный PHP-массив из config/web.php.
  2. Создаётся объект приложения: preInit() применяет критичные свойства (basePath), регистрируется обработчик ошибок, применяется остальная конфигурация, init() вызывает bootstrap() — подключаются расширения и компоненты из bootstrap.
  3. run() обрабатывает запрос: событие beforeRequest → разбор маршрута компонентом request → создание модуля/контроллера/действия → выполнение → событие afterRequest → отправка ответа.
  4. Скрипт получает код выхода и завершает работу.

Подробнее о каждом шаге — в разделе Жизненный цикл запроса.

Компоненты приложения#

Приложение — это Service Locator: набор именованных объектов, к которым обращаются как Yii::$app->id. Компонент создаётся при первом обращении и дальше переиспользуется в рамках запроса.

config/web.phpPHP
'components' => [
    'cache' => 'yii\caching\ApcCache',                 // просто имя класса
    'db' => [                                          // массив конфигурации
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=localhost;dbname=demo',
        'username' => 'root',
        'password' => '',
        'charset' => 'utf8',
    ],
    'search' => function () {                           // фабрика-замыкание
        return new app\components\SolrService('127.0.0.1');
    },
],

Если компонент нужен в каждом запросе, даже когда к нему явно не обращаются (например, log должен ловить сообщения с самого начала), добавьте его ID в bootstrap:

PHP
'bootstrap' => ['log'],

Встроенные компоненты#

У них фиксированные ID и классы по умолчанию — достаточно указать только нужные свойства.

ID Класс За что отвечает
requestyii\web\Requestпараметры запроса, заголовки, куки, разбор маршрута
responseyii\web\Responseкод состояния, заголовки, тело, форматирование ответа
urlManageryii\web\UrlManagerразбор и генерация URL, правила ЧПУ
useryii\web\Userтекущий аутентифицированный пользователь (только web)
sessionyii\web\Sessionсессия и flash-сообщения (только web)
dbyii\db\Connectionсоединение с БД; класс и dsn нужно указать явно
errorHandleryii\web\ErrorHandlerперехват ошибок и исключений
logyii\log\Dispatcherмаршрутизация сообщений лога по целям
viewyii\web\Viewрендеринг представлений, регистрация скриптов
assetManageryii\web\AssetManagerпубликация и подключение JS/CSS
formatteryii\i18n\Formatterформатирование дат, чисел, размеров
i18nyii\i18n\I18Nпереводы сообщений
maileryii\symfonymailer\Mailer / yii\swiftmailer\Mailerотправка писем
cacheпо соглашению yii\caching\Cacheкеш данных; не встроен, но ожидается многими компонентами
Проверь себя5

id и basePath. Второе определяет псевдоним @app, от которого считаются runtimePath, viewPath и другие пути.

Лениво — при первом обращении Yii::$app->id. Чтобы создать его при старте каждого запроса, ID добавляют в bootstrap.

beforeAction: приложение → модуль → контроллер. afterAction: контроллер → модуль → приложение.

'catchAll' => ['site/offline'] — все запросы пойдут в это действие.

Чтобы константу можно было определить раньше (например, в тестовом входном скрипте или на сервере) без правки кода — повторный define вызвал бы ошибку.