什麼是 Contract
Laravel 的「Contracts」是一組定義框架所提供核心服務的介面。例如,Illuminate\Contracts\Queue\Queue Contract 定義了 Job 佇列所需的方法;Illuminate\Contracts\Mail\Mailer Contract 則定義了寄送郵件所需的方法。
每個 Contract 都有框架提供的對應實作。例如,Laravel 提供各種驅動的佇列實作,以及使用 Symfony Mailer 的 mailer 實作。
所有 Laravel Contracts 都放在專用的 GitHub Repository 中。這是一個獨立且已抽離的套件,提供所有可用 Contract 的快速參考,非常適合在打造與 Laravel 服務串接的套件時使用。
Contract 只是介面,運作方式與 PHP 的介面完全相同。Laravel 為這些介面提供實作,並透過服務容器注入。
Contract 與 Facade 的差異
Facade 與輔助函式提供一種便利的方式,可以不必透過服務容器的型別提示解析 Contract 即能使用 Laravel 的服務。多數情況下,每個 Facade 都對應到一個 Contract。 Facade 與 Contract 主要差異如下:何時使用 Contract
選擇 Contract 或 Facade 通常是個人偏好或團隊風格。兩者都能協助你建立健全且易於測試的 Laravel 應用程式,而且兩者並非互斥。你可以在部分區塊使用 Facade,其他區塊仰賴 Contract。 以下情境下 Contract 特別有用:- 要與多個 PHP 框架協作的套件:使用
illuminate/contracts套件來定義與 Laravel 服務的介接,就不必在composer.json中要求 Laravel 具體實作。 - 想讓依賴顯式:只看建構子就能一眼看出這個類別依賴什麼。
- 想更換實作:透過服務容器可以輕鬆換成別的實作。
Contract 的使用方式
如何取得 Contract 的實作?其實非常簡單。 Laravel 中許多種類的類別,如控制器、事件監聽器、中介軟體、佇列 Job、路由閉包等,都是透過服務容器解析而來。因此,要取得 Contract 的實作,只需在被解析類別的建構子上「型別提示」該介面。 以下是一個事件監聽器範例:建立自訂 Contract
透過建立自己的 Contract,可以讓應用程式各組件間的相依關係更清晰。1
定義介面
在
app/Contracts 目錄建立介面。2
建立實作類別
建立實作 Contract 的類別。
3
在服務提供者中繫結
在服務提供者中將 Contract 與實作繫結。
4
透過型別提示接收注入
在控制器或其他類別的建構子加上型別提示。
Stripe 換成別的供應商時,只需修改一處繫結,控制器程式碼完全不必變動。
主要 Contract 一覽
以下為部分常用 Contract 與其對應 Facade 的對照表。
所有 Contract 的完整清單請見 illuminate/contracts repository。
下一步
Facade
了解 Facade 的機制與測試方式。