# 簡介
Laravel 中的契約是指框架提供的一系列定義核心服務的接口。 例如,`Illuminate\Contracts\Queue\Queue` 契約定義了隊列任務需要實現的方法,`Illuminate\Contracts\Mail\Mailer` 契約定義了發送郵件所需要實現的方法。
每一個契約都有框架提供的相應實現。例如,Laravel 為隊列提供了多個驅動的實現,郵件則由 `SwiftMailer` 驅動實現 。
所有 Laravel 契約都有其[對應的GitHub庫](https://github.com/illuminate/contracts),這為所有有效的契約提供了快速入門指南,同時也可以作為獨立、解耦的包被包開發者使用。
## 契約 Vs. 門面
Laravel `門面`為 Laravel 服務的使用提供了便捷方式 —— 不再需要從服務容器中類型提示和契約解析即可直接通過靜態門面調用。
不同于門面不需要再構造器中進行類型提示,契約允許你在類中定義顯式的依賴。有些開發者喜歡門面帶來的便捷,也有些開發者傾向于使用契約,他們喜歡定義明確的依賴。
> 注:大多數應用中,不管你使用門面還是契約,合適就好。不過,如果你是在構建一個擴展包,那么就應該使用契約,因為更容易測試。
# 何時使用契約
正如上面所討論的,大多數情況下使用契約還是門面取決于個人或團隊的喜好,契約和門面都可以用于創建強大的、測試友好的 Laravel 應用。只要你保持類的職責單一,你會發現使用契約和門面并沒有什么實質性的差別。
但是,對契約你可能還是有些疑問。例如,為什么要全部使用接口?使用接口是不是更復雜?下面讓我們從兩個方面來扒一扒為什么使用接口:松耦合和簡單。
## 松耦合
首先,讓我們看看一些緩存實現的緊耦合代碼:
~~~
<?php
namespace App\Orders;
class Repository
{
/**
* 緩存
*/
protected $cache;
/**
* 創建一個新的Repository實例
*
* @param \SomePackage\Cache\Memcached $cache
* @return void
*/
public function __construct(\SomePackage\Cache\Memcached $cache)
{
$this->cache = $cache;
}
/**
* 通過ID獲取訂單
*
* @param int $id
* @return Order
*/
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}
~~~
在這個類中,代碼和給定緩存實現緊密耦合,由于我們基于一個來自包的具體的緩存類,如果包的API變了,那么相應的,我們的代碼必須做修改。
類似的,如果我們想要替換底層的緩存技術(Memcached)為別的技術實現(Redis),我們將再一次不得不修改我們的代碼庫。我們的代碼庫應該并不知道誰提供的數據或者數據是怎么提供的。
我們可以基于一種簡單的、與提供者無關的接口來優化我們的代碼,從而替代上述那種實現:
~~~
<?php
namespace App\Orders;
use Illuminate\Contracts\Cache\Repository as Cache;
class Repository
{
/**
* 創建一個新的Repository實例
*
* @param Cache $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
}
~~~
現在代碼就不與任何特定提供者耦合,甚至與 Laravel 都是無關的。由于契約包不包含任何實現和依賴,你可以輕松的為給定契約編寫可選實現代碼,你可以隨意替換緩存實現而不用去修改任何緩存消費代碼。
## 簡單
當所有 Laravel 服務都統一在簡單接口中定義,很容易判斷給定服務提供的功能。契約可以充當框架特性的簡明文檔。
此外,基于簡單接口,代碼也更容易理解和維護。在一個龐大而復雜的類中,與其追蹤哪些方法是有效的,不如轉向簡單、干凈的接口。
# 如何使用契約
那么,如何實現契約呢?這很簡單。
Laravel中很多類都是通過`服務容器`進行解析,包括控制器,以及監聽器、中間件、隊列任務,甚至路由閉包。所以,要實現一個契約,需要在解析類的構造函數中類型提示這個契約接口。
例如,看看下面這個事件監聽器:
~~~
<?php
namespace App\Listeners;
use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Database;
class CacheOrderInformation
{
/**
* The Redis database implementation.
*/
protected $redis;
/**
* Create a new event handler instance.
*
* @param Database $redis
* @return void
*/
public function __construct(Database $redis)
{
$this->redis = $redis;
}
/**
* Handle the event.
*
* @param OrderWasPlaced $event
* @return void
*/
public function handle(OrderWasPlaced $event)
{
//
}
}
~~~
事件監聽器被解析的時候,服務容器會讀取構造函數中的類型提示,并注入適當的值。要學習更多關于服務容器的注冊細節,參考其文檔。
# 契約列表
下面是 Laravel 契約列表,以及其對應的“門面”:
| 契約 | 對應門面 |
|---|---|
|Illuminate\Contracts\Auth\Access\Authorizable | |
|Illuminate\Contracts\Auth\Access\Gate | `Gate` |
|Illuminate\Contracts\Auth\Authenticatable | |
|Illuminate\Contracts\Auth\CanResetPassword | |
|Illuminate\Contracts\Auth\Factory | `Auth` |
|Illuminate\Contracts\Auth\Guard | `Auth::guard()` |
|Illuminate\Contracts\Auth\PasswordBroker | `Password::broker()` |
|Illuminate\Contracts\Auth\PasswordBrokerFactory | `Password` |
|Illuminate\Contracts\Auth\StatefulGuard | |
|Illuminate\Contracts\Auth\SupportsBasicAuth | |
|Illuminate\Contracts\Auth\UserProvider | |
|Illuminate\Contracts\Bus\Dispatcher | `Bus` |
|Illuminate\Contracts\Bus\QueueingDispatcher | `Bus::dispatchToQueue()` |
|Illuminate\Contracts\Broadcasting\Factory | `Broadcast` |
|Illuminate\Contracts\Broadcasting\Broadcaster | `Broadcast::connection()` |
|Illuminate\Contracts\Broadcasting\ShouldBroadcast | |
|Illuminate\Contracts\Broadcasting\ShouldBroadcastNow | |
|Illuminate\Contracts\Cache\Factory | `Cache` |
|Illuminate\Contracts\Cache\Lock | |
|Illuminate\Contracts\Cache\LockProvider | |
|Illuminate\Contracts\Cache\Repository | `Cache::driver()` |
|Illuminate\Contracts\Cache\Store | |
|Illuminate\Contracts\Config\Repository | `Config` |
|Illuminate\Contracts\Console\Application | |
|Illuminate\Contracts\Console\Kernel | `Artisan` |
|Illuminate\Contracts\Container\Container | `App` |
|Illuminate\Contracts\Cookie\Factory | `Cookie` |
|Illuminate\Contracts\Cookie\QueueingFactory | `Cookie::queue()` |
|Illuminate\Contracts\Database\ModelIdentifier | |
|Illuminate\Contracts\Debug\ExceptionHandler | |
|Illuminate\Contracts\Encryption\Encrypter | `Crypt` |
|Illuminate\Contracts\Events\Dispatcher | `Event` |
|Illuminate\Contracts\Filesystem\Cloud | `Storage::cloud()` |
|Illuminate\Contracts\Filesystem\Factory | `Storage` |
|Illuminate\Contracts\Filesystem\Filesystem | `Storage::disk()` |
|Illuminate\Contracts\Foundation\Application | `App` |
|Illuminate\Contracts\Hashing\Hasher | `Hash` |
|Illuminate\Contracts\Http\Kernel | |
|Illuminate\Contracts\Logging\Log | `Log` |
|Illuminate\Contracts\Mail\MailQueue | `Mail::queue()` |
|Illuminate\Contracts\Mail\Mailable | |
|Illuminate\Contracts\Mail\Mailer | `Mail` |
|Illuminate\Contracts\Notifications\Dispatcher | `Notification` |
|Illuminate\Contracts\Notifications\Factory | `Notification` |
|Illuminate\Contracts\Pagination\LengthAwarePaginator | |
|Illuminate\Contracts\Pagination\Paginator | |
|Illuminate\Contracts\Pipeline\Hub | |
|Illuminate\Contracts\Pipeline\Pipeline | |
|Illuminate\Contracts\Queue\EntityResolver | |
|Illuminate\Contracts\Queue\Factory | `Queue` |
|Illuminate\Contracts\Queue\Job | |
|Illuminate\Contracts\Queue\Monitor | `Queue` |
|Illuminate\Contracts\Queue\Queue | `Queue::connection()` |
|Illuminate\Contracts\Queue\QueueableCollection | |
|Illuminate\Contracts\Queue\QueueableEntity | |
|Illuminate\Contracts\Queue\ShouldQueue | |
|Illuminate\Contracts\Redis\Factory | `Redis` |
|Illuminate\Contracts\Routing\BindingRegistrar | `Route` |
|Illuminate\Contracts\Routing\Registrar | `Route` |
|Illuminate\Contracts\Routing\ResponseFactory | `Response` |
|Illuminate\Contracts\Routing\UrlGenerator | `URL` |
|Illuminate\Contracts\Routing\UrlRoutable | |
|Illuminate\Contracts\Session\Session | `Session::driver()` |
|Illuminate\Contracts\Support\Arrayable | |
|Illuminate\Contracts\Support\Htmlable | |
|Illuminate\Contracts\Support\Jsonable | |
|Illuminate\Contracts\Support\MessageBag | |
|Illuminate\Contracts\Support\MessageProvider | |
|Illuminate\Contracts\Support\Renderable | |
|Illuminate\Contracts\Support\Responsable | |
|Illuminate\Contracts\Translation\Loader | |
|Illuminate\Contracts\Translation\Translator | `Lang` |
|Illuminate\Contracts\Validation\Factory | `Validator` |
|Illuminate\Contracts\Validation\ImplicitRule | |
|Illuminate\Contracts\Validation\Rule | |
|Illuminate\Contracts\Validation\ValidatesWhenResolved | |
|Illuminate\Contracts\Validation\Validator | `Validator::make()` |
|Illuminate\Contracts\View\Engine | |
|Illuminate\Contracts\View\Factory | `View` |
|Illuminate\Contracts\View\View | `View::make()` |
- 序言
- 新版特性
- 快速入門
- 升級指南
- 貢獻指南
- API文檔
- 安裝配置
- 目錄結構
- Homestead
- Valet
- 部署
- 核心概念
- 請求生命周期
- 服務容器
- 服務提供者
- 門面(Facades)
- 契約(Contracts)
- 框架基礎
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 生成 URL
- Session
- 驗證
- 錯誤處理
- 日志
- 前端開發
- Blade 模板
- 本地化
- 前端腳手架
- 編譯前端資源(Laravel Mix)
- 安全系列
- 登錄認證
- API 認證
- 授權
- 加密
- 哈希
- 重置密碼
- 進階系列
- Artisan 控制臺
- 集合
- 廣播
- 緩存
- 事件
- 文件存儲
- 輔助函數
- 郵件
- 通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫操作
- 快速入門
- 查詢構建器
- 分頁
- 遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 關聯關系
- 集合
- 訪問器 & 修改器
- API 資源類
- 序列化
- 應用測試
- 快速入門
- HTTP 測試
- 瀏覽器測試
- 數據庫測試
- 模擬
- 官方擴展包
- Cashier(訂閱支付解決方案)
- Envoy(遠程操作解決方案)
- Horizon(隊列系統解決方案)
- Passport(API 認證解決方案)
- Scout(全文搜索解決方案)
- Socialite(第三方登錄解決方案)
- 相關下載
- Laravel 5.6 中文文檔離線版
- Laravel 5.6 一鍵安裝包