"Contract" của Laravel là một bộ interface dùng để định nghĩa các core service mà framework cung cấp. Ví dụ: một Illuminate\Contracts\Queue\Queue
contract định nghĩa các phương thức cần thiết cho việc queueing job, trong khi Illuminate\Contracts\Mail\Mailer
contract định nghĩa các phương thức cần thiết để gửi e-mail.
Mỗi contract có một implementation tương ứng được cung cấp bởi framework. Ví dụ: Laravel cung cấp một implementation queue với nhiều driver khác nhau và một implementation mailer được phát triển bởi SwiftMailer.
Tất cả các contract của Laravel đều được lưu trữ trong GitHub của chúng. Điều này cung cấp một điểm tham chiếu nhanh cho tất cả các contract có sẵn, cũng như tách rời package để có thể được sử dụng khi xây dựng các package tương tác với các dịch vụ Laravel.
Facade của Laravel và các helper function sẽ cung cấp một cách đơn giản để sử dụng các service của Laravel mà không cần phải khai báo và resolve các contract ra khỏi container service. Trong hầu hết các trường hợp, mỗi facade có một contract tương ứng.
Không giống như facade, không yêu cầu bạn phải khởi tạo chúng trong hàm khởi tạo của class, các contract cho phép bạn định nghĩa rõ các phụ thuộc cho các class của bạn. Một số nhà phát triển thích định nghĩa rõ sự phụ thuộc trong class của họ giống như cách này và do đó họ thích sử dụng contract, trong khi các nhà phát triển khác lại thích sự tiện lợi của facade. Nói chung, hầu hết các ứng dụng đều có thể sử dụng facade mà không gặp vấn đề gì trong quá trình phát triển.
Quyết định sử dụng contract hay là facade sẽ tùy thuộc vào sở thích cá nhân và thị hiếu của nhóm phát triển. Cả contract và facade đều có thể được sử dụng để tạo ra application Laravel mạnh mẽ và được thử nghiệm tốt. Contract và facade không loại trừ lẫn nhau. Một số phần trong ứng dụng của bạn có thể sử dụng facade trong khi những phần khác lại sử dụng contract. Miễn là bạn giữ cho class trong giới hạn của nó, bạn sẽ nhận thấy có rất ít sự khác biệt giữa việc sử dụng contract và facade.
Nói chung, hầu hết các ứng dụng đều có thể sử dụng các facade mà không gặp vấn đề gì trong quá trình phát triển. Nếu bạn đang xây dựng một package tích hợp cho nhiều framework của PHP, bạn có thể muốn sử dụng package illuminate/contracts
để định nghĩa khả năng tích hợp của bạn với các service của Laravel mà không cần yêu cầu bạn phải implement một Laravel cụ thể trong file composer.json
của package.
Vậy, làm thế nào để bạn có thể lấy ra được một implementation của một contract? Nó thực sự khá đơn giản.
Có nhiều loại class trong Laravel được resolve thông qua service container, bao gồm cả controller, event listener, middleware, queued job và thậm chí là route closure. Vì vậy, để lấy được một implementation của một contract, bạn chỉ cần khai báo interface vào trong hàm khởi tạo của class mà cần được resolve.
Ví dụ, hãy xem event listener này:
<?php
namespace App\Listeners;
use App\Events\OrderWasPlaced;
use App\Models\User;
use Illuminate\Contracts\Redis\Factory;
class CacheOrderInformation
{
/**
* The Redis factory implementation.
*
* @var \Illuminate\Contracts\Redis\Factory
*/
protected $redis;
/**
* Create a new event handler instance.
*
* @param \Illuminate\Contracts\Redis\Factory $redis
* @return void
*/
public function __construct(Factory $redis)
{
$this->redis = $redis;
}
/**
* Handle the event.
*
* @param \App\Events\OrderWasPlaced $event
* @return void
*/
public function handle(OrderWasPlaced $event)
{
//
}
}
Khi event listener được resolve, service container sẽ đọc các khai báo có trong hàm khởi tạo của class và đưa vào các giá trị phù hợp. Để tìm hiểu thêm về việc đăng ký trong service container, hãy xem tài liệu này.
Bảng này cung cấp một tài liệu tham khảo nhanh cho tất cả các contract của Laravel và các facade tương ứng với chúng:
entry