Laravel5を入門時に、ServiceProvider、ServiceContainer、Facadeなどの言葉が避けて通れないほどの聞かれます。最初、Laravelの説明ページから一通りに関連説明を読みましたが、分かったような感じでしたが、実際に使ってみようとの時に、まだまだ分からないと感じました。一つ一つで理解するより、これらの関連性及び使い方までを勉強した方が理解しやすいと思って、理解したことを纏めました。
ServiceProvider、ServiceContainer、FacadeがLaravel5の基本構造に分類される
- これらの概念が基本構造(Architecture Foundations)に分類されて、深く理解する必要があるようです。
- 言葉で概念を説明することをやめて(説明する文書がいっぱいある)、イメージで理解したほうが良いでしょう
- ServiceContainerはLaravelフレームワークに組み込んだ器で、ServiceProviderから注入されたサービスを受け取っています。Facadeはパイプのようなもので、ServiceContainerから必要な時に、必要なサービスを吸出して、そのサービスの各メッソドをStaticのように操作します。

- プログラムの実行順序から見ると、LaravelがWebリクエストが受け取って時に、すべて(ServiceContainer)のサービスを登録して(この時に各サービスを実行しない)、Facadeに呼び出されて時に個々サービスのプログラムが実行されます。この点で見ると、大量なサービスが登録されても、呼び出さなければサービスが実行されず、パフォーマンスにあまり影響しないようです(実際のコーティングに、使用していないサービスプロバイダが登録されたままであまり問題にならないようです)。
簡単のケースではServiceContainerの使用をしなくても問題なし
ServiceProvider、ServiceContainer、Facadeで実装する
- 以下の処理でProviderとFacadeクラスを追加する
// artisanコマンドでServiceProviderのクラスのひな形追加
php artisan make:provider LDAPServiceProvider;
// app/providersフォルダの下にLDAPServiiceProvider.phpができた
// registerメッソドでLDAPサービスをServiceContainerに注入する
public function register()
{
// ServiceContainerに登録
$this->app->bind('ldap', function(){
// LDAPの接続変数の取得
$ad_option = Config::get('ldap.ad_options');
try {
// adLDAPを初期化し、インスタンスを返す
return new adLDAP( $ad_option );
}catch (adLDAPException $e) {
echo $e;
exit();
}
});
}
// このLDAPServiiceProviderをconfig/app.phpに登録する
'providers'=>[
...
App\Providers\LDAPServiceProvider::class,
...
]
// Laravel5がFacadaの初期ディレクトがない、app/facadesディレクトリを作成する
// Facadeクラス: LDAP.phpを作成する(artisanの生成コマンドがないらしい)
// getFacadeAccessorメッソドで、LDAPサービスを返す
protected static function getFacadeAccessor()
{
return 'ldap';
}
// このFacadeをエイリアス名(簡単に使えるため)をconfig/app.phpに登録する
'aliases'=>[
...
'LDAP' => App\Facades\LDAP::class,
...
]
// コントローラーでLDAPサービスを呼出して、ユーザー認証
protected function authentication(AuthenticateRequest $request)
{
// ログインリクエストからログイン名とパスワードを取得
$login_name = $request->input('login_name') ;
$password = $request->input('password') ;
// ログインユーザーの認証
$result = \LDAP::authenticate($login_name, $password );
return dump($result);
}
- ServiceContainerを利用して、各ロジックをサービス化することより、メリットとデメリットがあります
- メリット: 依存性が低減、拡張性がよい、テストがしやすい(Laravelの説明)
- デメリット: コードの量が多くなる、追跡が難しくなる(個人の感覚、慣れが必要かな?)