本文へ移動
Laravel Tips

サービスプロバイダ

アプリの起動のときに道具を登録するサービスプロバイダの書き方、register と boot の役目の違い、登録のしかた、読み込みを遅らせる方法を説明します。

サービスプロバイダは、アプリの起動のときに準備をする場所です。自分で作った部分も、Laravel 本体の機能も、ここで準備されます。

準備とは、おもに「登録する」ことです。登録するものは、サービスコンテナ(クラスを作って渡してくれる、道具箱のようなしくみ)への道具、イベントのリスナー(知らせを受けて動く処理)、ミドルウェア、ルートなどです。アプリの設定は、ほぼここに集まります。

Laravel の中でも、メール・キュー・キャッシュなどの準備に、何十ものサービスプロバイダが使われています。その多くは「遅延プロバイダ」です。リクエストのたびには読みこまれず、その機能が本当に必要になったときだけ読みこまれます。

自分で作ったサービスプロバイダは、すべて bootstrap/providers.php に登録します。

補足

Laravel がリクエストをどう扱っているか、内部の動きを知りたいときは、リクエストのライフサイクルのページを見てください。

サービスプロバイダを書く#

サービスプロバイダは、すべて Illuminate\Support\ServiceProvider クラスを受け継ぎます(親のクラスの機能をそのまま引き継ぐこと)。たいていのプロバイダは、register と boot の2つのメソッドを持ちます。

注意

register メソッドの中では、サービスコンテナへの登録だけをします。イベントのリスナー、ルート、そのほかの機能を、register の中で登録してはいけません。

Artisan の make:provider コマンドで、新しいプロバイダを作れます。作ったプロバイダは、bootstrap/providers.php に自動で登録されます。

bash
php artisan make:provider RiakServiceProvider

register メソッド#

くり返しになりますが、register の中では、サービスコンテナへの登録だけをします。イベントのリスナーやルートなどを登録してはいけません。register が動く時点では、ほかのサービスプロバイダがまだ読みこまれていないことがあります。そのサービスを、うっかり使ってしまうおそれがあるからです。

基本のサービスプロバイダを見てみます。プロバイダのどのメソッドの中でも、$app プロパティ(クラスの中の変数)で、サービスコンテナを使えます。

php
<?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
<?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
<?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 メソッドには、必要な道具の型を書けます。サービスコンテナが、必要な道具を自動で渡してくれます。

php
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
<?php

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

make:provider コマンドで作ったプロバイダは、このファイルに自動で足されます。プロバイダのクラスを手で作ったときは、配列に自分で足します。

php
<?php

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

遅延プロバイダ(読み込みを遅らせる)#

プロバイダが、サービスコンテナへの登録だけをするなら、登録した機能が本当に必要になるまで、読みこみを遅らせられます。毎回のリクエストでファイルから読みこまなくなるので、アプリが速くなります。

Laravel は、遅延プロバイダが用意するサービスの一覧を、そのプロバイダのクラスの名前といっしょに、まとめて取っておきます。そして、一覧の中のサービスを取り出そうとしたときにだけ、そのサービスプロバイダを読みこみます。

読みこみを遅らせるには、\Illuminate\Contracts\Support\DeferrableProvider インターフェースを実装し、provides メソッドを作ります。provides は、そのプロバイダがサービスコンテナに登録するものの一覧を返します。

php
<?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日時点の内容をもとに、日本語でまとめています。

ページの一覧