#Введение
При использовании любого инструмента в «реальной жизни» вы чувствуете себя увереннее, если понимаете, как этот инструмент работает. Разработка приложений не исключение. Когда вы понимаете, как работают ваши инструменты разработки, вы чувствуете себя комфортнее и увереннее при их использовании.
Цель этого документа — дать вам общее представление о том, как работает фреймворк Laravel. Познакомившись с общей структурой фреймворка, всё будет казаться менее «магическим», и вы будете увереннее создавать свои приложения. Если вы сразу не поймёте все термины, не расстраивайтесь! Просто постарайтесь получить базовое понимание происходящего, а ваши знания будут расти по мере изучения других разделов документации.
#Обзор жизненного цикла
#Первые шаги
Точка входа для всех запросов к приложению Laravel — файл public/index.php. Все запросы направляются к этому файлу настройками вашего веб-сервера (Apache / Nginx). Файл index.php содержит немного кода и служит отправной точкой для загрузки остальной части фреймворка.
Файл index.php загружает автозагрузчик, сгенерированный Composer, а затем получает экземпляр приложения Laravel из bootstrap/app.php. Первым действием самого Laravel является создание экземпляра приложения / service container.
#HTTP- и консольные ядра
Далее входящий запрос направляется либо в HTTP kernel, либо в console kernel, в зависимости от типа запроса, поступающего в приложение. Эти два ядра служат центральным местом, через которое проходят все запросы. Пока сосредоточимся на HTTP kernel, который находится в app/Http/Kernel.php.
HTTP kernel расширяет класс Illuminate\Foundation\Http\Kernel, который определяет массив bootstrappers, запускаемых до обработки запроса. Эти bootstrappers настраивают обработку ошибок, логирование, определяют окружение приложения и выполняют другие задачи, необходимые до фактической обработки запроса. Обычно эти классы управляют внутренней конфигурацией Laravel, о которой вам не нужно беспокоиться.
HTTP kernel также определяет список HTTP middleware, через которые должны пройти все запросы перед обработкой приложением. Эти middleware отвечают за чтение и запись HTTP-сессии, проверку, находится ли приложение в режиме обслуживания, проверку CSRF-токена и многое другое. Скоро мы подробнее обсудим их.
Сигнатура метода handle HTTP kernel довольно проста: он принимает Request и возвращает Response. Представьте kernel как большую чёрную коробку, которая представляет всё ваше приложение. Подайте на вход HTTP-запросы — и получите HTTP-ответы.
#Провайдеры сервисов
Одним из важнейших действий при загрузке ядра является загрузка провайдеров сервисов вашего приложения. Провайдеры сервисов отвечают за инициализацию всех различных компонентов фреймворка, таких как база данных, очередь, валидация и маршрутизация. Все провайдеры сервисов приложения настраиваются в массиве providers конфигурационного файла config/app.php.
Laravel перебирает этот список провайдеров и создаёт экземпляр каждого из них. После создания экземпляров вызывается метод register у всех провайдеров. Затем, когда все провайдеры зарегистрированы, вызывается метод boot у каждого провайдера. Это нужно для того, чтобы провайдеры могли полагаться на то, что все привязки контейнера уже зарегистрированы и доступны к моменту выполнения их метода boot.
Практически все основные функции, которые предоставляет Laravel, инициализируются и настраиваются через провайдеры сервисов. Поскольку они загружают и настраивают так много возможностей фреймворка, провайдеры сервисов являются самым важным элементом всего процесса загрузки Laravel.
#Маршрутизация
Одним из важнейших провайдеров сервисов в вашем приложении является App\Providers\RouteServiceProvider. Этот провайдер загружает файлы маршрутов, содержащиеся в директории routes вашего приложения. Откройте код RouteServiceProvider и посмотрите, как он работает!
После загрузки приложения и регистрации всех провайдеров сервисов, Request передаётся маршрутизатору для обработки. Маршрутизатор направит запрос к маршруту или контроллеру, а также выполнит любые middleware, назначенные конкретному маршруту.
Middleware предоставляют удобный механизм для фильтрации или проверки HTTP-запросов, поступающих в ваше приложение. Например, Laravel включает middleware, который проверяет, аутентифицирован ли пользователь вашего приложения. Если пользователь не аутентифицирован, middleware перенаправит его на страницу входа. Если же пользователь аутентифицирован, middleware позволит запросу продолжить обработку в приложении. Некоторые middleware назначаются всем маршрутам приложения, например, те, что определены в свойстве $middleware вашего HTTP kernel, а некоторые — только конкретным маршрутам или группам маршрутов. Подробнее о middleware можно узнать в полной документации по middleware.
Если запрос проходит через все middleware, назначенные совпавшему маршруту, будет выполнен маршрут или метод контроллера, а возвращённый ими ответ пройдёт обратно через цепочку middleware маршрута.
#Завершение
После того как маршрут или метод контроллера возвращает ответ, ответ проходит обратно через middleware маршрута, давая приложению возможность изменить или проверить исходящий ответ.
Наконец, когда ответ проходит через middleware, метод handle HTTP kernel возвращает объект ответа, и файл index.php вызывает метод send у возвращённого ответа. Метод send отправляет содержимое ответа в веб-браузер пользователя. Наше путешествие по жизненному циклу запроса Laravel завершено!
#Фокус на провайдерах сервисов
Провайдеры сервисов действительно являются ключом к загрузке приложения Laravel. Создаётся экземпляр приложения, регистрируются провайдеры сервисов, и запрос передаётся загруженному приложению. Всё действительно так просто!
Хорошее понимание того, как строится и загружается приложение Laravel через провайдеры сервисов, очень ценно. Провайдеры сервисов вашего приложения по умолчанию хранятся в директории app/Providers.
По умолчанию AppServiceProvider довольно пуст. Этот провайдер — отличное место для добавления собственной инициализации приложения и привязок в сервис-контейнер. Для крупных приложений вы можете создать несколько провайдеров сервисов, каждый из которых будет отвечать за более детальную инициализацию конкретных сервисов, используемых вашим приложением.