Appearance
Contracts 合约
介绍
Laravel 的 “合约” 是一组接口,用于定义框架提供的核心服务。例如, Illuminate\Contracts\Queue\Queue
协定定义将作业排队所需的方法,而 Illuminate\Contracts\Mail\Mailer
协定定义发送电子邮件所需的方法。
每个 Contract 都有框架提供的相应 implementation。例如,Laravel 提供了一个具有各种驱动程序的队列实现,以及一个由 Symfony Mailer 提供支持的 mailer 实现。
所有 Laravel 合约都位于他们自己的 GitHub 存储库中。这为所有可用的合约提供了一个快速参考点,以及一个在构建与 Laravel 服务交互的包时可以使用的单个解耦包。
Contracts vs. Facades
Laravel 的 facades 和 helper 函数提供了一种利用 Laravel 服务的简单方法,而无需在服务容器中进行类型提示和解析 Contract。在大多数情况下,每个 Facade 都有一个等效的合同。
与 facades 不同,facades 不需要你在类的构造函数中要求它们,Contract 允许你为类定义显式依赖项。一些开发人员喜欢以这种方式显式定义他们的依赖项,因此更喜欢使用 Contract,而其他开发人员则享受 Facade 的便利。通常,大多数应用程序在开发过程中都可以毫无问题地使用 Facade。
为什么使用 Contracts
使用合同或Facade的决定将归结为个人品味和您的开发团队的品味。Contract 和 Facades 都可用于创建健壮的、经过充分测试的 Laravel 应用程序。协定和 Facades 并不互斥。应用程序的某些部分可能使用 Facade,而其他部分则依赖于 Contract。只要你把班级的责任放在首位,你就会注意到使用合同和Facade之间的实际差异很小。
通常,大多数应用程序在开发过程中都可以毫无问题地使用 Facade。如果您正在构建一个与多个 PHP 框架集成的包,您可能希望使用 illuminate/contracts
包来定义与 Laravel 服务的集成,而无需在包的 composer.json
文件中要求 Laravel 的具体实现。
怎样使用 Contracts
那么,如何实现合约呢?其实很简单。
Laravel 中的许多类型的类都是通过服务容器解析的,包括控制器、事件监听器、中间件、排队作业,甚至路由闭包。因此,要获得 Contract 的实现,您只需在被解析的类的构造函数中对接口进行 “type-hint” 操作即可。
例如,看看这个事件监听器:
<?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
{
// ...
}
}
When the event listener is resolved, the service container will read the type-hints on the constructor of the class, and inject the appropriate value. To learn more about registering things in the service container, check out its documentation.
合约参考
下表提供了所有 Laravel 合约及其等效 facades 的快速参考: