{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == Поставщики услуг, или сервис-провайдеры (//service providers//), лежат в основе "первоначальной загрузки" всего Laravel. И ваше приложение, и все базовые сервисы Laravel загружаются через сервис-провайдеры. Но что мы понимаем под "первоначальной загрузкой"? В основном это **регистрация** таких вещей как привязки сервис-контейнера, слушатели событий, посредники и даже маршруты. Сервис-провайдеры - центральное место для настройки вашего приложения. Если вы откроете файл %%(t)config/app.php%%, поставляемый с Laravel, то вы увидите массив %%(t)providers%%. В нём перечислены все классы сервис-провайдеров, которые загружаются для вашего приложения. Конечно, многие из них являются «отложенными» (deferred), они не загружаются при каждом запросе, а только при необходимости. В этом обзоре вы узнаете, как создавать свои собственные сервис-провайдеры и регистрировать их в своём приложении. == Создание сервис-провайдеров == Все сервис-провайдеры наследуют класс %%(t)Illuminate\Support\ServiceProvider%%. В большинстве сервис-провайдеров есть методы %%register()%% и %%boot()%%. В методе %%register()%% вы должны **только привязывать свои классы в ((/docs/v5/container сервис-контейнер))**. Никогда не пытайтесь зарегистрировать в этом методе слушателей событий, маршруты и какие-либо другие возможности. С помощью Artisan CLI можно создать новый провайдер командой %%(sh)make:provider%%: %%(sh) php artisan make:provider RiakServiceProvider %% === Метод register() === Как уже было сказано, внутри метода %%register()%% вы должны только привязывать свои классы в ((/docs/v5/container сервис-контейнер)). Никогда не пытайтесь зарегистрировать в этом методе слушателей событий, маршруты и какие-либо другие возможности. Иначе может получиться, что вы обратитесь к сервису, предоставляемому сервис-провайдером, который ещё не был загружен. Давайте взглянем на простой сервис-провайдер. Из любого метода вашего сервис-провайдера у вас всегда есть доступ к свойству %%(t)$app%%, которое предоставляет доступ к сервис-контейнеру: %% app->singleton(Connection::class, function ($app) { //для версии 5.1 и ранее: //$this->app->singleton('Riak\Contracts\Connection', function ($app) { return new Connection(config('riak')); }); } } %% Этот сервис-провайдер только определяет метод %%register()%% и использует его, чтобы определить реализацию %%(t)Riak\Connection%% (для версии 5.1 и ранее - %%(t)Riak\Contracts\Connection%%) в сервис-контейнере. Если вы не поняли, как работает сервис-контейнер, прочитайте ((/docs/v5/container его документацию)). %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) Все сервис-провайдеры Laravel по-умолчанию размещены в namespace %%App\Providers%%. Там же разместится и наш класс. Но, естественно, вы всегда можете поменять его местоположение. Ваши сервис-провайдеры могут быть размещены где угодно, так чтобы Composer автоматически их загружал. %% === Метод %%(t)boot()%% === А что, если нам нужно зарегистрировать построитель представления в нашем сервис-провайдере? Это нужно делать в методе %%boot%%. **Этот метод вызывают после того, как все другие сервис-провайдеры были зарегистрированы.** Это значит, что у вас есть доступ ко всем другим сервисам, которые были зарегистрированы фреймворком. %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) ~%% namespace App\Providers; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider { /** * Загрузка любых сервисов приложения. * * @return void */ public function boot() { view()->composer('view', function () { // }); } } ~%% %% %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15) ~%% composer('view', function () { // }); } } ~%% %% %%(DOCNEW 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) ~%% composer('view', function () { // }); } /** * Привязка к контейнеру. * * @return void */ public function register() { // } } ~%% %% **Внедрение зависимостей метода %%boot()%%** Вы можете указать зависимости для метода %%boot()%% вашего сервис-провайдера. Сервис-контейнер автоматически внедрит те зависимости, которые вы зададите: %% use Illuminate\Contracts\Routing\ResponseFactory; public function boot(ResponseFactory $response) { $response->macro('caps', function ($value) { // }); } %% == Регистрация провайдеров == Все сервис-провайдеры регистрируются в файле %%config/app.php%% путем добавления имён их классов в массив %%(t)providers%%. Изначально в нём указан набор базовых сервис-провайдеров Laravel. Эти провайдеры загружают базовые компоненты Laravel, такие как обработчик почты, очередь, кэш и другие. Чтобы зарегистрировать свой сервис-провайдер, просто добавьте его в этот массив: %% 'providers' => [ // Другие сервис-провайдеры App\Providers\ComposerServiceProvider::class, ], %% == Отложенные провайдеры == Если ваш провайдер **только** регистрирует привязки в ((/docs/v5/container сервис-контейнере)), то вы можете отложить регистрацию до момента, когда одна из этих привязок будет запрошена из сервис-контейнера. Это позволит не дёргать файловую систему при каждом запросе, что увеличит производительность вашего приложения. Laravel собирает и хранит список всех сервисов, предоставляемых отложенными сервис-провайдерами, и их классов. Когда в процессе работы приложению понадобится один из этих сервисов, Laravel загрузит нужный сервис-провайдер. Для того, чтобы сделать сервис-провайдер отложенным, установите свойство %%(t)defer%% в %%(t)true%% и определите метод %%provides()%%. Метод %%provides()%% должен вернуть привязки сервис-контейнера, зарегистрированные в вашем провайдере: %% app->singleton(Connection::class, function ($app) { //Для версии 5.1 и ранее: //$this->app->singleton('Riak\Contracts\Connection', function ($app) { return new Connection($app['config']['riak']); }); } /** * Получить сервисы от провайдера. * * @return array */ public function provides() { return [Connection::class]; //Для версии 5.1 и ранее: //return ['Riak\Contracts\Connection']; } } %%