2.1. Жизненный цикл запроса
1. Введение
При использовании любого инструмента в "реальном мире" вы чувствуете себя увереннее, если понимаете, как он работает. Разработка приложений не является исключением. Когда вы понимаете, как работают ваши инструменты разработки, вы чувствуете себя комфортнее и увереннее при их использовании.
Цель этого документа — дать вам хорошее общее представление о том, как работает фреймворк Laravel. Чем лучше вы узнаете фреймворк в целом, тем менее "магическим" он будет казаться, и вы будете чувствовать себя увереннее при создании своих приложений. Если вы не сразу поймете все термины, не расстраивайтесь! Постарайтесь получить базовое понимание происходящего, а ваши знания будут расти по мере изучения других разделов документации.
2. Обзор жизненного цикла
2.1. Первые шаги
Точкой входа для всех запросов к приложению Laravel является файл public/index.php
. Все запросы
перенаправляются к этому файлу с помощью конфигурации вашего веб-сервера (Apache / Nginx). Файл
index.php
не содержит много кода. Вместо этого он является отправной точкой для загрузки остальной
части фреймворка.
Файл index.php
загружает автоматически сгенерированный автозагрузчик Composer, а затем получает
экземпляр приложения Laravel из файла bootstrap/app.php
. Первым действием, выполняемым самим Laravel,
является создание экземпляра приложения / сервис-контейнера.
2.2. HTTP-ядро / Консольное ядро
Затем входящий запрос отправляется либо в HTTP-ядро, либо в консольное ядро, в зависимости от типа запроса,
поступающего в приложение, с использованием методов handleRequest
или handleCommand
экземпляра приложения. Эти два ядра являются центральной точкой, через которую проходят все запросы. На данный
момент давайте сосредоточимся на HTTP-ядре, которое является экземпляром
Illuminate\Foundation\Http\Kernel
.
HTTP-ядро определяет массив bootstrappers
, которые будут выполнены до обработки запроса. Эти
bootstrappers настраивают обработку ошибок, конфигурируют логирование, определяют окружение приложения и выполняют другие
задачи, которые необходимо выполнить до непосредственной обработки запроса. Обычно эти классы занимаются
внутренней конфигурацией Laravel, о которой вам не нужно беспокоиться.
HTTP-ядро также отвечает за передачу запроса через стек middleware вашего приложения. Эти middleware обрабатывают чтение и запись HTTP-сессий, определяют, находится ли приложение в режиме обслуживания, проверяют CSRF-токен и многое другое. Мы подробно поговорим об этом позже.
Сигнатура метода handle
в HTTP-ядре довольно проста: он принимает Request
и возвращает
Response
. Представьте ядро как большую черную коробку, которая представляет все ваше приложение. Вы
подаете ему HTTP-запросы, и оно возвращает HTTP-ответы.
2.3. Сервис-Провайдеры
Одним из самых важных действий при инициализации ядра является загрузка сервис-провайдеров вашего приложения. Сервис-провайдеры отвечают за инициализацию всех различных компонентов фреймворка, таких как базы данных, очереди, валидация и маршрутизация.
Laravel будет проходить по этому списку сервис-провайдеров и создавать экземпляр каждого из них. После создания
экземпляров у всех сервис-провайдеров будет вызван метод register
. Затем, когда все сервис-провайдеры
будут зарегистрированы, у каждого из них будет вызван метод boot
. Это сделано для того, чтобы к
моменту выполнения метода boot
все привязки контейнера были зарегистрированы и доступны.
Практически каждая основная функция, предлагаемая Laravel, инициализируется и настраивается с помощью сервис-провайдера. Поскольку сервис-провайдеры инициализируют и настраивают множество функций, предлагаемых фреймворком, они являются самым важным аспектом всего процесса инициализации Laravel.
Хотя фреймворк внутренне использует десятки сервис-провайдеров, вы также можете создать свои собственные. Вы
можете найти список пользовательских или сторонних сервис-провайдеров, которые использует ваше приложение, в файле
bootstrap/providers.php
.
2.4. Маршрутизация
После инициализации приложения и регистрации всех сервис-провайдеров объект Request
будет передан
маршрутизатору для обработки. Маршрутизатор отправит запрос на маршрут или контроллер, а также выполнит любое
middleware, связанное с маршрутом.
Middleware предоставляют удобный механизм для фильтрации или анализа HTTP-запросов, поступающих в ваше
приложение. Например, Laravel включает middleware, которое проверяет, авторизован ли пользователь вашего
приложения. Если пользователь не авторизован, middleware перенаправит его на экран входа. Однако, если
пользователь авторизован, middleware позволит запросу продолжить обработку в приложении. Некоторые middleware
назначаются для всех маршрутов приложения, например PreventRequestsDuringMaintenance
, а некоторые
применяются только к определённым маршрутам или группам маршрутов. Подробнее о middleware вы можете узнать,
прочитав полную документацию по middleware.
Если запрос проходит через все middleware, назначенные для соответствующего маршрута, будет выполнен метод маршрута или контроллера, и ответ, возвращённый этим методом, будет отправлен обратно через цепочку middleware маршрута.
2.5. Завершение
После того как метод маршрута или контроллера вернёт ответ, этот ответ будет проходить обратно через middleware маршрута, предоставляя приложению возможность изменить или проанализировать исходящий ответ.
Наконец, после того как ответ проходит обратно через middleware, метод handle
HTTP-ядра возвращает
объект ответа в handleRequest
экземпляра приложения, и этот метод вызывает метод send
у
возвращённого ответа. Метод send
отправляет содержимое ответа в веб-браузер пользователя. На этом
наше путешествие по всему жизненному циклу запроса в Laravel завершено!
3. Фокус на сервис-провайдерах
Сервис-провайдеры действительно являются ключевым элементом инициализации приложения Laravel. Создаётся экземпляр приложения, регистрируются сервис-провайдеры, и запрос передаётся инициализированному приложению. Всё действительно так просто!
Чёткое понимание того, как приложение Laravel создаётся и инициализируется с помощью сервис-провайдеров, имеет
большую ценность. Пользовательские сервис-провайдеры вашего приложения хранятся в каталоге
app/Providers
.
По умолчанию AppServiceProvider
практически пуст. Этот провайдер отлично подходит для добавления
собственной инициализации и привязок сервисного контейнера вашего приложения. Для крупных приложений вы можете
создать несколько сервис-провайдеров, каждый из которых будет отвечать за более детальную инициализацию конкретных
сервисов, используемых вашим приложением.