Laravel Laravel
  • 前言

    • 发行说明
    • 升级向导
    • 贡献导引
    • API 文档
  • 入门指南

    • 安装
    • 配置
    • 文件夹结构
    • Homestead
    • Valet
  • 架构思想

    • 请求生命周期
    • 服务容器
    • 服务提供者
    • Facades:门面
    • Contracts:契约
  • 基础功能

    • 路由
    • 中间件
    • CSRF 保护
    • 控制器
    • 请求
    • 响应
    • 视图
    • Session
    • 表单验证
    • 错误 & 日志
  • 前端开发

    • Blade 模板
    • 本地化
    • 前端脚手架
    • 编译资源
  • 安全

    • 身份认证
    • API 身份认证
    • 授权
    • 加密
    • 哈希
    • 重置密码
  • 深入话题

    • Artisan 命令行
    • 广播
    • 缓存
    • 集合
    • 事件
    • 文件存储
    • 辅助函数
    • Mail
    • 消息通知
    • 扩展包开发
    • 队列
    • 任务调度
  • 数据库

    • 快速入门
    • 查询构造器
    • 分页
    • 数据库迁移
    • 数据填充
    • Redis
  • Eloquent ORM

    • 快速入门
    • 关联关系
    • Eloquent 集合
    • 修改器
    • 序列化
  • 测试

    • 快速入门
    • HTTP 测试
    • 浏览器测试
    • 数据库测试
    • 测试模拟器Mocking
  • 官方扩展包

    • Cashier
    • Envoy部署工具
    • PassportOAuth 认证
    • Scout全文搜索
    • Socialite社会化登录
Icon

提示 您正在浏览旧版本的 Laravel 的文档. 请考虑将你的项目升级到 Laravel 11.x.

1 0

Contracts
5.4
8.x 7.x 6.x 5.8 5.7 5.6 5.5 5.4 5.3 5.2 5.1

Laravel 5.4 中文文档 /

未匹配的标注
本文档最新版为 8.x,旧版本可能放弃维护,推荐阅读最新版!

契约 (Contracts)

  • 简介
    • 契约 (Contracts) Vs. 门面 (Facades)
  • 何时使用契约
    • 低耦合
    • 简单性
  • 如何使用 Contracts
  • Contract 参考

简介

Laravel 的 契约(Contracts ) 是一系列框架用来定义核心服务的接口。例如,Illuminate\Contracts\Queue\Queue 契约中定义了队列任务所需的方法,而 Illuminate\Contracts\Mail\Mailer 契约中定义了发送电子邮件所需的方法。

框架对每个契约都提供了相应的实现。例如,Laravel 为队列提供了各种驱动的实现,为邮件提供了由 SwiftMailer 驱动的实现。

所有 Laravel 契约都有相应的 GitHub 库 ,这给所有可用的契约提供了一个快速参考指南,同时也可单独作为低耦合的扩展包给其他包开发者去使用。

契约 (contracts) VS 门面 (facades)

门面 (facades) 和一些辅助函数提供了一种使用 Laravel 服务的简单方法,即不再需要通过类型约束和在服务容器之外解析契约。 在大多数情况下,每个门面都有一个等效契约。

不像门面,门面不需要你在类构造函数中约束什么,契约则是需要你明显地定义依赖关系。 一些开发人员喜欢契约这种方式明显地去定义它们的依赖关系,而另一些开发人员则更喜欢门面带来的便捷。

{tip} 对于大多数应用程序来说不管是使用门面还是契约只要你喜欢都行。但是 ,如果你正在构建一个扩展包,为了方便测试建议考虑使用契约比较好。

何时使用 contracts

综上所述,使用契约或者门面很大程度上归结于个人或者开发团队的喜好。不管是契约还是门面都可以创建出强大的、容易测试的 Laravel 应用程序。 如果你长期关注类的单一职责,你会注意到使用契约和门面其实没多少实际意义上的区别。

然而,你可能还是会有几个关于契约的问题。像是,为什么要使用接口?使用接口会不会变得更加复杂?下面让我们简单阐述一下使用接口的原因:低耦合和简单性。

低耦合

首先,让我们回顾一些与缓存实现的高耦合代码。如下:

<?php

namespace App\Orders;

class Repository
{
    /**
     * 缓存实例。
     */
    protected $cache;

    /**
     * 创建一个仓库实例。
     *
     * @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 ),那又得再一次修改这个 repository 类。而 repository 类不应该知道这么多信息,比如关于谁提供了这些数据,或是他们又是如何提供的等等。

比起上面的做法,我们可以使用一个简单、和扩展包无关的接口来改进代码:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository
{
    /**
     * 缓存实例。
     */
    protected $cache;

    /**
     * 创建一个仓库实例。
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }
}

现在,更改之后的代码没有与任何扩展包耦合,甚至是 Laravel 。而契约扩展包不包含实现和依赖,你可以轻松地对任何契约包进行实现,比如不需要修改任何关于缓存的代码就可以替换缓存实现。

简单性

当所有的 Laravel 服务都使用简洁的接口定义,就能够很容易决定一个服务需要提供的功能。 可以将契约视为说明框架特色的简洁文档。

除此之外,当依赖的接口足够简洁时,代码的可读性和可维护性会大大提高。比起搜索一个大型复杂的类里有哪些可用的方法,不如检索一个简单、干净的接口来参考更妥当。

如何使用 contracts

那么,如何获取一个契约的实现呢?这其实很简单。

Laravel 中的许多类型的类都是通过 服务容器 解析出来的。包括控制器、事件监听器、中间件、任务队列,甚至路由的闭包。所以说,要获得一个契约的实现,你只需要解析在类的构造函数中相应的类型约束即可。

例如,看看这个事件监听器:

<?php

namespace App\Listeners;

use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Database;

class CacheOrderInformation
{
    /**
     * Redis 数据库实现。
     */
    protected $redis;

    /**
     * 创建事件处理器实例。
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * 处理事件。
     *
     * @param  OrderWasPlaced  $event
     * @return void
     */
    public function handle(OrderWasPlaced $event)
    {
        //
    }
}

当事件监听器被解析时,服务容器会从构造函数里读取到类型约束,并注入对应的值。 想了解关于容器的注册绑定,可以查看 服务容器。

Contract 参考

下面的表格提供了 Laravel 契约及其对应的门面的参考:

Contract References Facade
Illuminate\Contracts\Auth\Factory Auth
Illuminate\Contracts\Auth\PasswordBroker Password
Illuminate\Contracts\Bus\Dispatcher Bus
Illuminate\Contracts\Broadcasting\Broadcas...  
Illuminate\Contracts\Cache\Repository Cache
Illuminate\Contracts\Cache\Factory Cache::driver()
Illuminate\Contracts\Config\Repository Config
Illuminate\Contracts\Container\Container App
Illuminate\Contracts\Cookie\Factory Cookie
Illuminate\Contracts\Cookie\QueueingFactor... Cookie::queue()
Illuminate\Contracts\Encryption\Encrypter Crypt
Illuminate\Contracts\Events\Dispatcher Event
Illuminate\Contracts\Filesystem\Cloud  
Illuminate\Contracts\Filesystem\Factory File
Illuminate\Contracts\Filesystem\Filesystem File
Illuminate\Contracts\Foundation\Applicatio... App
Illuminate\Contracts\Hashing\Hasher Hash
Illuminate\Contracts\Logging\Log Log
Illuminate\Contracts\Mail\MailQueue Mail::queue()
Illuminate\Contracts\Mail\Mailer Mail
Illuminate\Contracts\Queue\Factory Queue::driver()
Illuminate\Contracts\Queue\Queue Queue
Illuminate\Contracts\Redis\Database Redis
Illuminate\Contracts\Routing\Registrar Route
Illuminate\Contracts\Routing\ResponseFacto... Response
Illuminate\Contracts\Routing\UrlGenerator URL
Illuminate\Contracts\Support\Arrayable  
Illuminate\Contracts\Support\Jsonable  
Illuminate\Contracts\Support\Renderable  
Illuminate\Contracts\Validation\Factory Validator::make()
Illuminate\Contracts\Validation\Validator  
Illuminate\Contracts\View\Factory View::make()
Illuminate\Contracts\View\View  
上一篇 下一篇

成为Laravel合作伙伴

Laravel Partners是提供一流Laravel开发和咨询服务的精英商店。我们每个合作伙伴都可以帮助您制定一个精美,结构完善的项目.

我们的伙伴
Laravel
亮点
  • Our Team
  • 发布说明
  • 入门
  • 路由
  • Blade 模板
  • 身份验证
  • 用户授权
  • Artisan 控制台
  • 数据库
  • Eloquent ORM
  • 测试
资源
  • Laravel Bootcamp
  • Laracasts
  • Laravel News
  • Laracon
  • Laracon EU
  • Laracon India
  • Jobs
  • Forums
  • Trademark
  • 版本发布时间
  • 包开发
  • 命令行应用
  • TALL stack全栈开发
  • Blade UI Kit
  • 前端资源构建
伙伴
  • WebReinvent
  • Vehikl
  • Tighten
  • 64 Robots
  • Active Logic
  • Byte 5
  • Curotec
  • Cyber-Duck
  • DevSquad
  • Jump24
  • Kirschbaum
生态系统
  • Cashier
  • Dusk
  • Echo
  • Envoyer
  • Forge
  • Horizon
  • Nova
  • Octane
  • Sail
  • Sanctum
  • Scout
  • Spark
  • Telescope
  • Valet
  • Vapor

Laravel是一个具有表达力,优雅语法的Web应用程序框架。我们认为,发展必须是一种令人愉悦的创造力,才能真正实现。Laravel试图通过减轻大多数Web项目中使用的常见任务来减轻开发的痛苦.

Laravel是Taylor Otwell的商标.
Copyright © 2011-2025 Laravel中文网 LLC.

  • Twitter
  • GitHub
  • Discord
Laravel 全栈开发网 推荐使用阿里云 按Ctrl+D试试