#はじめに
Laravelの「コントラクト」は、フレームワークが提供するコアサービスを定義するインターフェイスのセットです。例えば、Illuminate\Contracts\Queue\Queue コントラクトはジョブのキューイングに必要なメソッドを定義し、Illuminate\Contracts\Mail\Mailer コントラクトはメール送信に必要なメソッドを定義します。
各コントラクトにはフレームワークが提供する対応する実装があります。例えば、Laravelは複数のドライバーを持つキューの実装や、Symfony Mailer を利用したメール送信の実装を提供しています。
すべてのLaravelコントラクトは専用のGitHubリポジトリにあります。ここでは利用可能なコントラクトを素早く参照できるほか、Laravelサービスと連携するパッケージを作成する際に利用できる単一の独立したパッケージとしても活用できます。
#コントラクトとファサードの違い
Laravelのファサードやヘルパー関数は、サービスコンテナからコントラクトをタイプヒントして解決することなく、Laravelのサービスを簡単に利用できます。ほとんどの場合、各ファサードには対応するコントラクトがあります。
ファサードはクラスのコンストラクターで明示的に要求する必要がありませんが、コントラクトはクラスの依存関係を明示的に定義できます。依存関係を明確に定義したい開発者はコントラクトを好み、便利さを重視する開発者はファサードを好みます。一般的に、ほとんどのアプリケーションは開発中にファサードを問題なく使えます。
#コントラクトを使うタイミング
コントラクトとファサードのどちらを使うかは、個人やチームの好みによります。どちらも堅牢でテストしやすいLaravelアプリケーションを作成できます。コントラクトとファサードは排他的ではありません。アプリケーションの一部はファサードを使い、他の部分はコントラクトに依存することも可能です。クラスの責務を明確に保てば、コントラクトとファサードの実際の違いはほとんど感じません。
一般的に、ほとんどのアプリケーションは開発中にファサードを問題なく使えます。複数のPHPフレームワークと連携するパッケージを作成する場合は、illuminate/contracts パッケージを使ってLaravelのサービスとの連携を定義し、パッケージの composer.json にLaravelの具体的な実装を要求しないようにできます。
#コントラクトの使い方
では、コントラクトの実装をどうやって取得するのでしょうか?実はとても簡単です。
Laravelでは、コントローラー、イベントリスナー、ミドルウェア、キュージョブ、ルートクロージャなど、多くのクラスがサービスコンテナを通じて解決されます。したがって、コントラクトの実装を取得するには、解決されるクラスのコンストラクターでインターフェイスをタイプヒントすればよいのです。
例えば、次のイベントリスナーを見てみましょう:
<?php
namespace App\Listeners;
use App\Events\OrderWasPlaced;
use App\Models\User;
use Illuminate\Contracts\Redis\Factory;
class CacheOrderInformation
{
/**
* 新しいイベントハンドラーのインスタンスを作成します。
*/
public function __construct(
protected Factory $redis,
) {}
/**
* イベントを処理します。
*/
public function handle(OrderWasPlaced $event): void
{
// ...
}
}
イベントリスナーが解決される際、サービスコンテナはクラスのコンストラクターのタイプヒントを読み取り、適切な値を注入します。サービスコンテナへの登録方法については、ドキュメントを参照してください。
#コントラクトリファレンス
この表は、すべてのLaravelコントラクトと対応するファサードを素早く参照できるようにまとめたものです: