このリポジトリはPHP Webアプリフレームワークである、LaravelのLTSバージョンである5.5の公式英文ドキュメントを日本語へ翻訳しています。
This project is maintained by okinaka
サービスプロバイダは、Laravelアプリケーション全体の起動処理における、初めの心臓部です。皆さんのアプリケーションと同じく、Laravelのコアサービス全部もサービスプロバイダを利用し、初期起動処理を行っています。
ところで「初期起動処理」とは何を意味しているのでしょうか? サービスコンテナの結合や、イベントリスナ、フィルター、それにルートなどを登録することを一般的に意味しています。サービスプロバイダはアプリケーション設定の中心部です。
Laravelに含まれているconfig/app.php
ファイルを開けば、providers
配列が見つかるでしょう。そこにある全サービスプロバイダクラスが、アプリケーションのためにロードされます。もちろんほとんどのプロバイダは、全てのリクエストで必ずロードされるとは限らず、そのプロバイダが提供するサービスが、実際に必要なときにのみロードされる「遅延」プロバイダです。
この概論ではサービスプロバイダの書き方と、Laravelアプリケーションに登録する方法を学びます。
全てのサービスプロバイダは、Illuminate\Support\ServiceProvider
クラスを拡張します。ほとんどのサービスプロバイダは、register
とboot
メソッドを持っています。register
メソッドの中ではサービスコンテナへの登録だけを行わなくてはなりません。他のイベントリスナやルート、その他の機能の一部でも、register
メソッドの中で登録しようとしてはいけません。
make:provider
Artisanコマンドラインにより、新しいプロバイダが生成できます。
php artisan make:provider RiakServiceProvider
既に説明した通り、register
メソッドの中ではサービスコンテナに何かを結合することだけを行わなければなりません。イベントリスナやルート、その他のどんな機能もregister
メソッドの中では決して行ってはいけません。これを守らないと、サービスプロバイダがまだロードしていないサービスを意図せず使ってしまう羽目になるでしょう。
では、基本的なサービスプロバイダを見てみましょう。サービスプロバイダメソッド中であれば、いつでも$app
プロパティを利用でき、サービスコンテナへアクセスできます。
<?php
namespace App\Providers;
use Riak\Connection;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* コンテナへの結合登録
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection(config('riak'));
});
}
}
このサービスプロバイダではregister
メソッドだけが定義されています。そして、サービスコンテナにRiak\Connection
の実装を定義しています。サービスコンテナがどのように動作するのかまだ理解できていなければ、ドキュメントで調べてください。
ではイベントリスナをサービスプロバイダで登録する必要がある場合は、どうすればよいのでしょうか? boot
メソッドの中で行ってください。このメソッドは、他の全サービスプロバイダが登録し終えてから呼び出されます。つまりフレームワークにより登録された、他のサービス全てにアクセスできるのです。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* 全アプリケーションサービスの初期起動処理
*
* @return void
*/
public function boot()
{
view()->composer('view', function () {
//
});
}
}
サービスプロバイダのboot
メソッドでは、依存をタイプヒントで指定できます。サービスコンテナが、必要な依存を自動的に注入します。
use Illuminate\Contracts\Routing\ResponseFactory;
public function boot(ResponseFactory $response)
{
$response->macro('caps', function ($value) {
//
});
}
全てのサービスプロバイダは、config/app.php
設定ファイルで登録されています。このファイルには、サービスプロバイダの名前をリストしてあるproviders
配列が含まれています。この配列にはデフォルトとして、メール送信、キュー、キャッシュなどのLaravelコアのサービスプロバイダが登録されています。
プロバイダを登録するには、この配列に追加するだけです。
'providers' => [
// Other Service Providers
App\Providers\ComposerServiceProvider::class,
],
もし皆さんのプロバイダが、サービスコンテナへコンテナ結合を登録するだけであるなら、その結合が実際に必要になるまで登録を遅らせる方が良いでしょう。こうしたプロバイダのローディングを遅らせるのは、リクエストがあるたびにファイルシステムからロードされなくなるため、アプリケーションのパフォーマンスを向上させます。
Laravelは遅延サービスプロバイダが提示した全サービスのリストをコンパイルし、サービスプロバイダのクラス名と共に保存します。その後、登録されているサービスのどれか一つを依存解決する必要が起きた時のみ、Laravelはそのサービスプロバイダをロードします。
プロバイダを遅延ロードするには、defer
プロパティにtrue
をセットし、provides
メソッドを定義します。provides
メソッドはそのプロバイダで登録するサービスコンテナ結合名を返します。
<?php
namespace App\Providers;
use Riak\Connection;
use Illuminate\Support\ServiceProvider;
class RiakServiceProvider extends ServiceProvider
{
/**
* プロバイダのローディングを遅延させるフラグ
*
* @var bool
*/
protected $defer = true;
/**
* サービスプロバーダーの登録
*
* @return void
*/
public function register()
{
$this->app->singleton(Connection::class, function ($app) {
return new Connection($app['config']['riak']);
});
}
/**
* このプロバイダにより提供されるサービス
*
* @return array
*/
public function provides()
{
return [Connection::class];
}
}