Skip to content

Сервис-провайдеры

1. Введение

Сервис-провайдеры — это центральное место для инициализации всех приложений Laravel. Ваше собственное приложение, так же как и все основные сервисы Laravel, инициализируются через сервис-провайдеры.

Но что мы имеем в виду под "инициализацией"? В общем смысле, это означает регистрацию различных элементов, включая привязки в сервис-контейнере, слушатели событий, посредники и даже маршруты. Сервис-провайдеры — это центральное место для настройки вашего приложения.

Laravel использует десятки сервис-провайдеров для инициализации своих основных сервисов, таких как почтовая служба, очередь, кэш и другие. Многие из этих провайдеров являются "отложенными", то есть они не будут загружаться при каждом запросе, а только тогда, когда предоставляемые ими сервисы действительно понадобятся.

Все пользовательские сервис-провайдеры регистрируются в файле bootstrap/providers.php. В следующей документации вы узнаете, как писать собственные сервис-провайдеры и регистрировать их в вашем Laravel-приложении.

lightbulb

Если вы хотите узнать больше о том, как Laravel обрабатывает запросы и работает изнутри, ознакомьтесь с нашей документацией о жизненном цикле запроса в Laravel.

2. Создание сервис-провайдеров

Все сервис-провайдеры наследуются от класса Illuminate\Support\ServiceProvider. Большинство сервис-провайдеров содержат методы register и boot. Внутри метода register вы должны только связывать объекты в сервис-контейнере. Никогда не пытайтесь регистрировать слушатели событий, маршруты или любую другую функциональность внутри метода register.

Интерфейс командной строки Artisan может сгенерировать новый провайдер с помощью команды make:provider. Laravel автоматически зарегистрирует ваш новый провайдер в файле bootstrap/providers.php вашего приложения:

php artisan make:provider RiakServiceProvider

2.1. Метод Register

Как упоминалось ранее, в методе 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
{
/**
* Register any application services.
*/
public function register(): void
{
$this->app->singleton(Connection::class, function (Application $app) {
return new Connection(config('riak'));
});
}
}

Этот сервис-провайдер определяет только метод register и использует его для определения реализации App\Services\Riak\Connection в сервис-контейнере. Если вы еще не знакомы с сервис-контейнером Laravel, ознакомьтесь с его документацией.

2.1.1. Свойства 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
{
/**
* All of the container bindings that should be registered.
*
* @var array
*/
public $bindings = [
ServerProvider::class => DigitalOceanServerProvider::class,
];
 
/**
* All of the container singletons that should be registered.
*
* @var array
*/
public $singletons = [
DowntimeNotifier::class => PingdomDowntimeNotifier::class,
ServerProvider::class => ServerToolsProvider::class,
];
}

2.2. Метод Boot

Итак, что если нам нужно зарегистрировать view-composer (композер представлений) в нашем сервис-провайдере? Это следует делать в методе boot. Этот метод вызывается после регистрации всех остальных сервис-провайдеров, что означает, что у вас есть доступ ко всем другим сервисам, зарегистрированным фреймворком:

<?php
 
namespace App\Providers;
 
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
 
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
View::composer('view', function () {
// ...
});
}
}

2.2.1. Внедрение зависимостей в метод Boot

Вы можете указать зависимости для метода boot вашего сервис-провайдера. Сервис-контейнер автоматически внедрит все необходимые зависимости:

use Illuminate\Contracts\Routing\ResponseFactory;
 
/**
* Bootstrap any application services.
*/
public function boot(ResponseFactory $response): void
{
$response->macro('serialized', function (mixed $value) {
// ...
});
}

3. Регистрация провайдеров

Все сервис-провайдеры регистрируются в конфигурационном файле bootstrap/providers.php. Этот файл возвращает массив, содержащий имена классов сервис-провайдеров вашего приложения:

<?php
 
return [
App\Providers\AppServiceProvider::class,
];

Когда вы вызываете Artisan-команду make:provider, Laravel автоматически добавляет сгенерированный провайдер в файл bootstrap/providers.php. Однако, если вы создали класс провайдера вручную, вам следует вручную добавить его в массив:

<?php
 
return [
App\Providers\AppServiceProvider::class,
App\Providers\ComposerServiceProvider::class,
];

4. Отложенные провайдеры