イントロダクション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に含まれているconfig/app.php
ファイルを開けば、providers
配列が見つかるでしょう。そこにある全サービスプロバイダクラスが、アプリケーションのためにロードされます。もちろんほとんどのプロバイダは、全てのリクエストで必ずロードされるとは限らず、そのプロバイダが提供するサービスが、実際に必要なときにのみロードされる「遅延」プロバイダです。If you open the
config/app.php
file included with
Laravel, you will see a providers
array. These are all of the service provider classes
that will be loaded for your application. Of course,
many of these are "deferred" providers,
meaning they will not be loaded on every request,
but only when the services they provide are actually
needed.
この概論ではサービスプロバイダの書き方と、Laravelアプリケーションに登録する方法を学びます。In this overview you will learn how to write your own service providers and register them with your Laravel application.
サービスプロバイダの記述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コマンドラインにより、新しいプロバイダが生成できます。The Artisan CLI can generate a
new provider via the make:provider
command:
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 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
の実装を定義しています。サービスコンテナがどのように動作するのかまだ理解できていなければ、ドキュメントで調べてください。This service provider only
defines a register
method, and uses
that method to define an implementation of
Riak\Connection
in the service
container. If you don't understand how the service
container works, check out its
documentation[/docs/{{version}}/container].
BootメソッドThe Boot Method
ではイベントリスナをサービスプロバイダで登録する必要がある場合は、どうすればよいのでしょうか?
boot
メソッドの中で行ってください。このメソッドは、他の全サービスプロバイダが登録し終えてから呼び出されます。つまりフレームワークにより登録された、他のサービス全てにアクセスできるのです。So, what if we need to register a
view composer 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\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* 全アプリケーションサービスの初期起動処理
*
* @return void
*/
public function boot()
{
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)
{
$response->macro('caps', function ($value) {
//
});
}
プロバイダの登録Registering Providers
全てのサービスプロバイダは、config/app.php
設定ファイルで登録されています。このファイルには、サービスプロバイダの名前をリストしてあるproviders
配列が含まれています。この配列にはデフォルトとして、メール送信、キュー、キャッシュなどのLaravelコアのサービスプロバイダが登録されています。All service providers are
registered in the config/app.php
configuration file. This file contains a
providers
array where you can list the
class names of your service providers. By default, a
set of Laravel core service providers are listed in
this array. These providers bootstrap the core
Laravel components, such as the mailer, queue,
cache, and others.
プロバイダを登録するには、この配列に追加するだけです。To register your provider, simply add it to the array:
'providers' => [
// Other Service Providers
App\Providers\ComposerServiceProvider::class,
],
遅延プロバイダ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.
プロバイダを遅延ロードするには、defer
プロパティーにtrue
をセットし、provides
メソッドを定義します。provides
メソッドはそのプロバイダで登録するサービスコンテナ結合名を返します。To defer the loading of a
provider, set the defer
property to
true
and define a provides
method. The provides
method should
return the service container bindings registered by
the provider:
<?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];
}
}