Документация Laravel 10.x
Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.
Сервис-провайдеры - центральное место для всех инициализаций Laravel-приложений. Ваше собственное приложение, а также все основные службы Laravel, инициализируются через сервис-провайдеры.
Но что мы имеем в виду под "инициализацией"? В общем, мы имеем в виду регистрацию вещей, включая регистрацию привязок контейнера служб, слушателей событий, промежуточного ПО и даже маршрутов. Сервис-провайдеры - центральное место для конфигурации вашего приложения.
Если вы откроете файл config/app.php
, включенный в Laravel, вы увидите массив providers
. В этом массиве перечислены все классы сервис-провайдеров, которые будут загружены для вашего приложения. По умолчанию в этом массиве перечислены основные сервис-провайдеры Laravel. Эти провайдеры откладывают загрузку, что означает, что они не будут загружены при каждом запросе, а только когда будут фактически нужны их службы.
В этом обзоре вы узнаете, как написать свои собственные сервис-провайдеры и зарегистрировать их в вашем приложении Laravel.
Примечание Если вы хотите узнать больше о том, как Laravel обрабатывает запросы и внутренне функционирует, ознакомьтесь с нашей документацией о жизненном цикле запроса.
Все сервис-провайдеры расширяют класс Illuminate\Support\ServiceProvider
. Большинство сервис-провайдеров содержат методы register
и boot
. Внутри метода register
вы должны только регистрировать вещи в контейнере служб. Никогда не пытайтесь регистрировать слушателей событий, маршруты или любую другую функциональность внутри метода register
.
Artisan CLI может сгенерировать новый провайдер с помощью команды make:provider
:
php artisan make:provider RiakServiceProvider
Как упоминалось ранее, внутри метода register
вы должны только регистрировать вещи в контейнере служб. Никогда не пытайтесь регистрировать слушателей событий, маршруты или любую другую функциональность внутри метода register
. В противном случае вы можете случайно использовать службу, предоставляемую сервис-провайдером, который еще не загрузился.
Давайте рассмотрим базовый сервис-провайдер. Внутри любого метода вашего сервис-провайдера у вас всегда есть доступ к свойству $app
, которое предоставляет доступ к контейнеру служб:
<?php namespace App\Providers; use App\Services\Riak\Connection;use Illuminate\Contracts\Foundation\Application;use Illuminate\Support\ServiceProvider; class RiakServiceProvider extends ServiceProvider{ /** * Регистрация любых служб приложения. */ public function register(): void { $this->app->singleton(Connection::class, function (Application $app) { return new Connection(config('riak')); }); }}
Этот сервис-провайдер определяет только метод register
и использует его для определения реализации App\Services\Riak\Connection
в контейнере служб. Если вы еще не знакомы с контейнером служб Laravel, ознакомьтесь с его документацией.
bindings
и singletons
Если ваш сервис-провайдер регистрирует много простых привязок, вы можете использовать свойства bindings
и singletons
вместо ручной регистрации каждой привязки контейнера. Когда фреймворк загружает сервис-провайдер, он автоматически проверит эти свойства и зарегистрирует их привязки:
<?php namespace App\Providers; use App\Contracts\DowntimeNotifier;use App\Contracts\ServerProvider;use App\Services\DigitalOceanServerProvider;use App\Services\PingdomDowntimeNotifier;use App\Services\ServerToolsProvider;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * Все привязки контейнера, которые должны быть зарегистрированы. * * @var array */ public $bindings = [ ServerProvider::class => DigitalOceanServerProvider::class, ]; /** * Все синглтоны контейнера, которые должны быть зарегистрированы. * * @var array */ public $singletons = [ DowntimeNotifier::class => PingdomDowntimeNotifier::class, ServerProvider::class => ServerToolsProvider::class, ];}
Итак, что делать, если нам нужно зарегистрировать композер представлений внутри нашего сервис-провайдера? Это следует сделать в методе boot
. Этот метод вызывается после регистрации всех остальных сервис-провайдеров, что означает, что у вас есть доступ ко всем остальным службам, зарегистрированным фреймворком:
<?php namespace App\Providers; use Illuminate\Support\Facades\View;use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider{ /** * Запуск служб приложения. */ public function boot(): void { View::composer('view', function () { // ... }); }}
Вы можете указывать зависимости для метода boot
своего сервис-провайдера. Контейнер служб автоматически внедрит любые зависимости, которые вам нужны:
use Illuminate\Contracts\Routing\ResponseFactory; /** * Запуск служб приложения. */public function boot(ResponseFactory $response): void{ $response->macro('serialized', function (mixed $value) { // ... });}
Все сервис-провайдеры регистрируются в файле конфигурации config/app.php
. Этот файл содержит массив providers
, где вы можете перечислить классы ваших сервис-провайдеров. По умолчанию в этот массив уже включены основные сервис-провайдеры Laravel. Они инициализируют основные компоненты Laravel, такие как почтовик, очередь, кэш и другие.
Чтобы зарегистрировать свой провайдер, добавьте его в массив:
'providers' => ServiceProvider::defaultProviders()->merge([ // Другие службы. App\Providers\ComposerServiceProvider::class,])->toArray(),
Если ваш провайдер только регистрирует привязки в контейнере служб, вы можете отложить его регистрацию до тех пор, пока не потребуется одна из зарегистрированных привязок. Отложение загрузки такого провайдера улучшит производительность вашего приложения, поскольку он не загружается с файловой системы при каждом запросе.
Laravel компилирует и сохраняет список всех служб, предоставляемых отложенными сервис-провайдерами, а также имя их класса. Тогда, только когда вы пытаетесь получить одну из этих служб, Laravel загружает сервис-провайдер.
Для отложенной загрузки провайдера реализуйте интерфейс \Illuminate\Contracts\Support\DeferrableProvider
и определите метод provides
. Метод provides
должен возвращать привязки контейнера служб, зарегистрированные провайдером:
<?php namespace App\Providers; use App\Services\Riak\Connection;use Illuminate\Contracts\Foundation\Application;use Illuminate\Contracts\Support\DeferrableProvider;use Illuminate\Support\ServiceProvider; class RiakServiceProvider extends ServiceProvider implements DeferrableProvider{ /** * Регистрация любых служб приложения. */ public function register(): void { $this->app->singleton(Connection::class, function (Application $app) { return new Connection($app['config']['riak']); }); } /** * Получите службы, предоставленные этим провайдером. * * @return array<int, string> */ public function provides(): array { return [Connection::class]; }}