メインコンテンツまでスキップ

サービスプロバイダ

はじめに

サービスプロバイダは、すべての Laravel アプリケーションのブートストラップの中心的な場所です。あなた自身のアプリケーションだけでなく、Laravel のすべてのコアサービスもサービスプロバイダを介してブートストラップされます。

しかし、ここで「ブートストラップ」とは何を意味するのでしょうか?一般的には、サービスコンテナのバインディング、イベントリスナー、ミドルウェア、さらにはルートなどを登録することを指します。サービスプロバイダは、アプリケーションを構成する中心的な場所です。

Laravel は、メーラー、キュー、キャッシュなどのコアサービスをブートストラップするために、内部で数十のサービスプロバイダを使用しています。これらのプロバイダの多くは「遅延ロード」プロバイダであり、提供されるサービスが実際に必要とされるときにのみロードされます。

すべてのユーザー定義のサービスプロバイダは、bootstrap/providers.php ファイルに登録されます。以下のドキュメントでは、独自のサービスプロバイダを作成し、それらを Laravel アプリケーションに登録する方法を学ぶことができます。

注記

Laravel がリクエストを処理し、内部でどのように動作するかについて詳しく知りたい場合は、Laravel のリクエストライフサイクルに関するドキュメントをご覧ください。

サービスプロバイダの作成

すべてのサービスプロバイダは Illuminate\Support\ServiceProvider クラスを拡張しています。ほとんどのサービスプロバイダには register メソッドと boot メソッドが含まれています。register メソッドでは、**サービスコンテナ**にのみバインドするべきです。register メソッド内でイベントリスナーやルートなどの機能を登録しようとしてはいけません。

Artisan CLI は make:provider コマンドを介して新しいプロバイダを生成できます。Laravel は自動的に新しいプロバイダをアプリケーションの bootstrap/providers.php ファイルに登録します。

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
{
/**
* 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のサービスコンテナにまだ慣れていない場合は、そのドキュメントをチェックしてください。

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,
];
}

ブートメソッド

では、サービスプロバイダー内でビューコンポーザを登録する必要がある場合はどうすればよいでしょうか?これは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 () {
// ...
});
}
}

ブートメソッドの依存性注入

サービスプロバイダーのbootメソッドに依存関係を型ヒントすることができます。サービスコンテナは必要な依存関係を自動的にインジェクトします。

    use Illuminate\Contracts\Routing\ResponseFactory;

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

プロバイダの登録

すべてのサービスプロバイダは bootstrap/providers.php 構成ファイルに登録されます。このファイルは、アプリケーションのサービスプロバイダのクラス名を含む配列を返します:

    <?php

return [
App\Providers\AppServiceProvider::class,
];

make:provider Artisan コマンドを実行すると、Laravel は生成されたプロバイダを自動的に bootstrap/providers.php ファイルに追加します。ただし、プロバイダクラスを手動で作成した場合は、プロバイダクラスを配列に手動で追加する必要があります:

    <?php

return [
App\Providers\AppServiceProvider::class,
App\Providers\ComposerServiceProvider::class, // [tl! add]
];

遅延プロバイダ

プロバイダがサービスコンテナでのバインディングのみを登録している場合、登録を必要とするバインディングが実際に必要になるまで登録を遅延させることができます。このようなプロバイダの読み込みを遅延させることで、アプリケーションのパフォーマンスが向上し、リクエストごとにファイルシステムから読み込まれなくなります。

Laravel は、遅延サービスプロバイダが提供するすべてのサービスのリストとそのサービスプロバイダクラスの名前をコンパイルして保存します。その後、これらのサービスのうちの1つを解決しようとするときにのみ、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
{
/**
* Register any application services.
*/
public function register(): void
{
$this->app->singleton(Connection::class, function (Application $app) {
return new Connection($app['config']['riak']);
});
}

/**
* Get the services provided by the provider.
*
* @return array<int, string>
*/
public function provides(): array
{
return [Connection::class];
}
}