サービスプロバイダ
アプリの起動のときに道具を登録するサービスプロバイダの書き方、register と boot の役目の違い、登録のしかた、読み込みを遅らせる方法を説明します。
サービスプロバイダは、アプリの起動のときに準備をする場所です。自分で作った部分も、Laravel 本体の機能も、ここで準備されます。
準備とは、おもに「登録する」ことです。登録するものは、サービスコンテナ(クラスを作って渡してくれる、道具箱のようなしくみ)への道具、イベントのリスナー(知らせを受けて動く処理)、ミドルウェア、ルートなどです。アプリの設定は、ほぼここに集まります。
Laravel の中でも、メール・キュー・キャッシュなどの準備に、何十ものサービスプロバイダが使われています。その多くは「遅延プロバイダ」です。リクエストのたびには読みこまれず、その機能が本当に必要になったときだけ読みこまれます。
自分で作ったサービスプロバイダは、すべて bootstrap/providers.php に登録します。
補足
Laravel がリクエストをどう扱っているか、内部の動きを知りたいときは、リクエストのライフサイクルのページを見てください。
サービスプロバイダを書く#
サービスプロバイダは、すべて Illuminate\Support\ServiceProvider クラスを受け継ぎます(親のクラスの機能をそのまま引き継ぐこと)。たいていのプロバイダは、register と boot の2つのメソッドを持ちます。
注意
register メソッドの中では、サービスコンテナへの登録だけをします。イベントのリスナー、ルート、そのほかの機能を、register の中で登録してはいけません。
Artisan の make:provider コマンドで、新しいプロバイダを作れます。作ったプロバイダは、bootstrap/providers.php に自動で登録されます。
php artisan make:provider RiakServiceProvider
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 の作り方をサービスコンテナに登録しています。
bindings と singletons のプロパティ#
かんたんな登録がたくさんあるときは、1つずつ書く代わりに、bindings と singletons のプロパティが使えます。プロバイダが読みこまれるときに、フレームワークがこの2つのプロパティを見て、自動で登録してくれます。
<?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,
];
}
| プロパティ | 説明 |
|---|---|
$bindings |
bind で登録したい、インターフェース(約束事)と実装(中身を書いたクラス)の組の配列 |
$singletons |
singleton で登録したい(一度だけ作る)、インターフェースと実装の組の配列 |
boot メソッド#
では、サービスプロバイダの中で、ビューコンポーザ(ビューを表示するときに、決まった処理を動かすしくみ)を登録したいときはどうするのでしょう。それは、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 メソッドへの依存性の注入#
boot メソッドには、必要な道具の型を書けます。サービスコンテナが、必要な道具を自動で渡してくれます。
use Illuminate\Contracts\Routing\ResponseFactory;
/**
* Bootstrap any application services.
*/
public function boot(ResponseFactory $response): void
{
$response->macro('serialized', function (mixed $value) {
// ...
});
}
register と boot の違い#
| メソッド | 呼ばれるとき | してよいこと |
|---|---|---|
register |
最初に、すべてのプロバイダで呼ばれる | サービスコンテナへの登録だけ |
boot |
すべてのプロバイダの register が終わったあと |
ビューコンポーザなど、ほかのサービスを使う処理 |
サービスプロバイダを登録する#
サービスプロバイダは、すべて bootstrap/providers.php に登録します。このファイルは、アプリのサービスプロバイダのクラス名の配列を返します。
<?php
return [
App\Providers\AppServiceProvider::class,
];
make:provider コマンドで作ったプロバイダは、このファイルに自動で足されます。プロバイダのクラスを手で作ったときは、配列に自分で足します。
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\ComposerServiceProvider::class,
];
遅延プロバイダ(読み込みを遅らせる)#
プロバイダが、サービスコンテナへの登録だけをするなら、登録した機能が本当に必要になるまで、読みこみを遅らせられます。毎回のリクエストでファイルから読みこまなくなるので、アプリが速くなります。
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];
}
}
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。