Skip to content

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 的快速参考:

ContractReferences Facade
Illuminate\Contracts\Auth\Access\Authorizable 
Illuminate\Contracts\Auth\Access\GateGate
Illuminate\Contracts\Auth\Authenticatable 
Illuminate\Contracts\Auth\CanResetPassword 
Illuminate\Contracts\Auth\FactoryAuth
Illuminate\Contracts\Auth\GuardAuth::guard()
Illuminate\Contracts\Auth\PasswordBrokerPassword::broker()
Illuminate\Contracts\Auth\PasswordBrokerFactoryPassword
Illuminate\Contracts\Auth\StatefulGuard 
Illuminate\Contracts\Auth\SupportsBasicAuth 
Illuminate\Contracts\Auth\UserProvider 
Illuminate\Contracts\Broadcasting\BroadcasterBroadcast::connection()
Illuminate\Contracts\Broadcasting\FactoryBroadcast
Illuminate\Contracts\Broadcasting\ShouldBroadcast 
Illuminate\Contracts\Broadcasting\ShouldBroadcastNow 
Illuminate\Contracts\Bus\DispatcherBus
Illuminate\Contracts\Bus\QueueingDispatcherBus::dispatchToQueue()
Illuminate\Contracts\Cache\FactoryCache
Illuminate\Contracts\Cache\Lock 
Illuminate\Contracts\Cache\LockProvider 
Illuminate\Contracts\Cache\RepositoryCache::driver()
Illuminate\Contracts\Cache\Store 
Illuminate\Contracts\Config\RepositoryConfig
Illuminate\Contracts\Console\Application 
Illuminate\Contracts\Console\KernelArtisan
Illuminate\Contracts\Container\ContainerApp
Illuminate\Contracts\Cookie\FactoryCookie
Illuminate\Contracts\Cookie\QueueingFactoryCookie::queue()
Illuminate\Contracts\Database\ModelIdentifier 
Illuminate\Contracts\Debug\ExceptionHandler 
Illuminate\Contracts\Encryption\EncrypterCrypt
Illuminate\Contracts\Events\DispatcherEvent
Illuminate\Contracts\Filesystem\CloudStorage::cloud()
Illuminate\Contracts\Filesystem\FactoryStorage
Illuminate\Contracts\Filesystem\FilesystemStorage::disk()
Illuminate\Contracts\Foundation\ApplicationApp
Illuminate\Contracts\Hashing\HasherHash
Illuminate\Contracts\Http\Kernel 
Illuminate\Contracts\Mail\Mailable 
Illuminate\Contracts\Mail\MailerMail
Illuminate\Contracts\Mail\MailQueueMail::queue()
Illuminate\Contracts\Notifications\DispatcherNotification
Illuminate\Contracts\Notifications\FactoryNotification
Illuminate\Contracts\Pagination\LengthAwarePaginator 
Illuminate\Contracts\Pagination\Paginator 
Illuminate\Contracts\Pipeline\Hub 
Illuminate\Contracts\Pipeline\PipelinePipeline
Illuminate\Contracts\Queue\EntityResolver 
Illuminate\Contracts\Queue\FactoryQueue
Illuminate\Contracts\Queue\Job 
Illuminate\Contracts\Queue\MonitorQueue
Illuminate\Contracts\Queue\QueueQueue::connection()
Illuminate\Contracts\Queue\QueueableCollection 
Illuminate\Contracts\Queue\QueueableEntity 
Illuminate\Contracts\Queue\ShouldQueue 
Illuminate\Contracts\Redis\FactoryRedis
Illuminate\Contracts\Routing\BindingRegistrarRoute
Illuminate\Contracts\Routing\RegistrarRoute
Illuminate\Contracts\Routing\ResponseFactoryResponse
Illuminate\Contracts\Routing\UrlGeneratorURL
Illuminate\Contracts\Routing\UrlRoutable 
Illuminate\Contracts\Session\SessionSession::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\TranslatorLang
Illuminate\Contracts\Validation\FactoryValidator
Illuminate\Contracts\Validation\ValidatesWhenResolved 
Illuminate\Contracts\Validation\ValidationRule 
Illuminate\Contracts\Validation\ValidatorValidator::make()
Illuminate\Contracts\View\Engine 
Illuminate\Contracts\View\FactoryView
Illuminate\Contracts\View\ViewView::make()