Skip to main content

什麼是 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 主要差異如下:
Facade 不需要在建構子中要求,但 Contract 可作為明確依賴宣告於建構子。部分開發者偏好這種明確的依賴宣告而使用 Contract;也有部分開發者偏好 Facade 的便利。通常,大多數應用程式在開發時使用 Facade 都能運作良好。

何時使用 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 的機制與測試方式。
最後修改於 2026年8月2日