イントロダクションIntroduction
サービスプロバイダは、Laravelアプリケーション全体の起動処理における、初めの心臓部です。皆さんのアプリケーションと同じく、Laravelのコアサービス全部もサービスプロバイダを利用し、初期起動処理を行っています。Service providers are the central place of all Laravel application bootstrapping. Your own application, as well as all of Laravel's core services, are bootstrapped via service providers.
ところで「初期起動処理」とは何を意味しているのでしょうか?サービスコンテナによる結合や、イベントリスナ、フィルター、それにルートなどを登録することを一般的に意味しています。サービスプロバイダはアプリケーション設定の中心部です。But, what do we mean by "bootstrapped"? In general, we mean registering things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application.
Laravelは、メーラー、キュー、キャッシュなどのコアサービスを初期起動するために、内部で何十ものサービスプロバイダを使用しています。これらのプロバイダの多くは、「遅延」プロバイダであり、すべてのリクエストでロードされるのではなく、提供するサービスが実際に必要になったときにのみロードすることを意味します。Laravel uses dozens of service providers internally to bootstrap its core services, such as the mailer, queue, cache, and others. Many of these providers are "deferred" providers, meaning they will not be loaded on every request, but only when the services they provide are actually needed.
ユーザー定義サービスプロバイダは全て、bootstrap/providers.php
ファイルへ登録します。このドキュメントの以降で、独自のサービスプロバイダを作成し、Laravelアプリケーションへ登録する方法を学びます。All user-defined service providers are registered in the bootstrap/providers.php
file. In the following documentation, you will learn how to write your own service providers and register them with your Laravel application.
リクエストライフサイクルに関するドキュメントを確認してください。[!NOTE]
Note: Laravelがリクエストをどのように処理し、内部で動作しているかについて詳しく知りたい場合は、Laravelの
If you would like to learn more about how Laravel handles requests and works internally, check out our documentation on the Laravel request lifecycle[/docs/{{version}}/lifecycle].
サービスプロバイダの記述Writing Service Providers
すべてのサービスプロバイダは、Illuminate\Support\ServiceProvider
クラスを拡張します。ほとんどのサービスプロバイダは、register
とboot
メソッドを持っています。register
メソッドの中では**サービスコンテナへの登録だけ**を行わなくてはなりません。他のイベントリスナやルート、その他の機能の一部でも、register
メソッドの中で登録しようとしてはいけません。All service providers extend the Illuminate\Support\ServiceProvider
class. Most service providers contain a register
and a boot
method. Within the register
method, you should only bind things into the service container[/docs/{{version}}/container]. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register
method.
make:provider
Artisanコマンドラインにより、新しいプロバイダを生成できます。Laravelは、アプリケーションのbootstrap/providers.php
ファイルへ、新しいプロバイダーを自動的に登録します。The Artisan CLI can generate a new provider via the make:provider
command. Laravel will automatically register your new provider in your application's bootstrap/providers.php
file:
php artisan make:provider RiakServiceProvider
RegisterメソッドThe Register Method
すでに説明した通り、register
メソッドの中ではサービスコンテナに何かを結合することだけを行わなければなりません。イベントリスナやルート、その他のどんな機能もregister
メソッドの中では決して行ってはいけません。これを守らないと、サービスプロバイダがまだロードしていないサービスを意図せず使ってしまう羽目になるでしょう。As mentioned previously, within the register
method, you should only bind things into the service container[/docs/{{version}}/container]. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register
method. Otherwise, you may accidentally use a service that is provided by a service provider which has not loaded yet.
では、基本的なサービスプロバイダを見てみましょう。サービスプロバイダメソッド中であれば、いつでも$app
プロパティを利用でき、サービスコンテナへアクセスできます。Let's take a look at a basic service provider. Within any of your service provider methods, you always have access to the $app
property which provides access to the service container:
<?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のサービスコンテナにまだ慣れていない方は、ドキュメントで確認してください。This service provider only defines a register
method, and uses that method to define an implementation of App\Services\Riak\Connection
in the service container. If you're not yet familiar with Laravel's service container, check out its documentation[/docs/{{version}}/container].
bindings
とsingletons
プロパティThe bindings
and singletons
Properties
サービスプロバイダでシンプルな結合をたくさん登録しているのであれば、各コンテナ結合を自力で登録する代わりに、bindings
とsingletons
プロパティを使いたくなるでしょう。フレームワークにより、サービスプロバイダがロードされる時点で、これらのプロパティがチェックされ、結合を登録します。If your service provider registers many simple bindings, you may wish to use the bindings
and singletons
properties instead of manually registering each container binding. When the service provider is loaded by the framework, it will automatically check for these properties and register their bindings:
<?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メソッドThe Boot Method
では、ビューコンポーサをサービスプロバイダで登録する必要がある場合は、どうすればよいのでしょうか? boot
メソッドの中で行ってください。このメソッドは、他の全サービスプロバイダが登録し終えてから呼び出されます。つまりフレームワークにより登録された、他のサービスすべてにアクセスできるのです。So, what if we need to register a view composer[/docs/{{version}}/views#view-composers] within our service provider? This should be done within the boot
method. This method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework:
<?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メソッドの依存注入Boot Method Dependency Injection
サービスプロバイダのboot
メソッドでは、依存をタイプヒントで指定できます。サービスコンテナが、必要な依存を自動的に注入します。You may type-hint dependencies for your service provider's boot
method. The service container[/docs/{{version}}/container] will automatically inject any dependencies you need:
use Illuminate\Contracts\Routing\ResponseFactory;
/**
* アプリケーションの全サービスの初期起動処理
*/
public function boot(ResponseFactory $response): void
{
$response->macro('serialized', function (mixed $value) {
// ...
});
}
プロバイダの登録Registering Providers
全てのサービスプロバイダは、bootstrap/providers.php
設定ファイルで登録します。このファイルは、アプリケーションのサービスプロバイダのクラス名を含む配列を返します。All service providers are registered in the bootstrap/providers.php
configuration file. This file returns an array that contains the class names of your application's service providers:
<?php
return [
App\Providers\AppServiceProvider::class,
];
make:providers
Artisanコマンドを実行すると、Laravelは生成したプロバイダを自動的に、bootstrap/providers.php
ファイルへ追加します。しかし、自分でプロバイダクラスを作成した場合は、プロバイダクラスを配列へ手作業で追加する必要があります。When you invoke the make:provider
Artisan command, Laravel will automatically add the generated provider to the bootstrap/providers.php
file. However, if you have manually created the provider class, you should manually add the provider class to the array:
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\ComposerServiceProvider::class, // [tl! add]
];
遅延プロバイダDeferred Providers
もし皆さんのプロバイダが、サービスコンテナへコンテナ結合を登録するだけであるなら、その結合が実際に必要になるまで登録を遅らせる方が良いでしょう。こうしたプロバイダのローディングを遅らせるのは、リクエストがあるたびにファイルシステムからロードされなくなるため、アプリケーションのパフォーマンスを向上させます。If your provider is only registering bindings in the service container[/docs/{{version}}/container], you may choose to defer its registration until one of the registered bindings is actually needed. Deferring the loading of such a provider will improve the performance of your application, since it is not loaded from the filesystem on every request.
Laravelは遅延サービスプロバイダが提示した全サービスのリストをコンパイルし、サービスプロバイダのクラス名と共に保存します。その後、登録されているサービスのどれか一つを依存解決する必要が起きた時のみ、Laravelはそのサービスプロバイダをロードします。Laravel compiles and stores a list of all of the services supplied by deferred service providers, along with the name of its service provider class. Then, only when you attempt to resolve one of these services does Laravel load the service provider.
プロバイダを遅延ロードするには、\Illuminate\Contracts\Support\DeferrableProvider
インターフェイスを実装し、provides
メソッドを定義します。provides
メソッドはそのプロバイダで登録したサービスコンテナ結合を返します。To defer the loading of a provider, implement the \Illuminate\Contracts\Support\DeferrableProvider
interface and define a provides
method. The provides
method should return the service container bindings registered by the provider:
<?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];
}
}