Laravel5中contracts详解


Posted in PHP onMarch 02, 2015

我们先来看看官方文档中对contracts的定义:

Laravel's Contracts are a set of interfaces that define the core services provided by the framework.
意思是说Laravel的Contracts是一个由 框架提供 的定义了 核心服务接口 的集合。

也就是说,每一个Contract都是一个接口,对应一个框架核心服务。

那它的意义何在?官网给出的解释也很简单:使用接口是为了 松耦合 和 简单 。

先不讲大道理,先来点干货,看看怎么使用contract

先浏览下contracts接口列表:

Illuminate\Contracts\Auth\Guard

Illuminate\Contracts\Auth\PasswordBroker

Illuminate\Contracts\Bus\Dispatcher

Illuminate\Contracts\Cache\Repository

Illuminate\Contracts\Cache\Factory

Illuminate\Contracts\Config\Repository

Illuminate\Contracts\Container\Container

Illuminate\Contracts\Cookie\Factory

Illuminate\Contracts\Cookie\QueueingFactory

Illuminate\Contracts\Encryption\Encrypter

Illuminate\Contracts\Routing\Registrar

…… 太多了,懒得继续贴了,官网手册里有。我们就拿 Illuminate\Contracts\Routing\Registrar 这个contract来演示一下吧。
首先,打开 app/Providers/AppServiceProvider.php,注意register方法:

public function register()

{

    $this->app->bind(

        'Illuminate\Contracts\Auth\Registrar',

        'App\Services\Registrar'

    );

}

$this->app 就是Application对象,也是容器对象,通过 $this->app->bind 方法我们绑定了一个实现Illuminate\Contracts\Auth\Registrar接口的类App\Services\Registrar。

注意,Illuminate\Contracts\Auth\Registrar就是一个contract。App\Services\Registrar 这个类文件在 app/Services/Registrar.php。

接着我们看 App\Http\Controllers\Auth\AuthController 这个控制器类,看到它有 __construct 构造函数:

public function __construct(Guard $auth, Registrar $registrar)

{

    $this->auth = $auth;

    $this->registrar = $registrar;
    $this->middleware('guest', ['except' => 'getLogout']);

}

它有两个参数,对应的类命名空间在脚本开头可以看到:

use Illuminate\Contracts\Auth\Guard;

use Illuminate\Contracts\Auth\Registrar;

这两个都是contract,但我们这里就拿 Registrar 说,我们注意到这里面只是通过参数类型指明了$registrar的接口类型,而实际调用的时候实际上是 App\Services\Registrar 这个类,这就是依赖注入的特性了,Laravel会自动在容器中搜索实现了接口Illuminate\Contracts\Auth\Registrar的类或对象,有的话就取出来作为实际参数传到构造函数里。

整个使用流程其实就可以总结为两个步骤:

向容器中注册实现contract接口的对象。
构造函数参数类型指定为contract接口类,框架会自动找到符合条件的对象。
那么再来说说contract的好处。

松耦合

官网给了一个例子解释什么是紧耦合以及Contract接口为何能够松耦合。

先来看看紧耦合的代码:

<?php namespace App\Orders;

class Repository {

    /**

     * The cache.

     */

    protected $cache;

    /**

     * Create a new repository instance.

     *

     * @param  \SomePackage\Cache\Memcached  $cache

     * @return void

     */

    public function __construct(\SomePackage\Cache\Memcached $cache)

    {

        $this->cache = $cache;

    }

    /**

     * Retrieve an Order by ID.

     *

     * @param  int  $id

     * @return Order

     */

    public function find($id)

    {

        if ($this->cache->has($id))

        {

            //

        }

    }

}

可以看到构造函数中注入了一个详细的缓存实现 \SomePackage\Cache\Memcached ,如果换Redis作为缓存服务器或者更改了api方法,就需要修改,而如果项目很大,你不知道还有多少地方需要修改。

那么,Contract接口是如何解决这个问题的?请看代码:

<?php namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository {

    /**

     * Create a new repository instance.

     *

     * @param  Cache  $cache

     * @return void

     */

    public function __construct(Cache $cache)

    {

        $this->cache = $cache;

    }

}

注意,缓存实现我们使用了一个接口,也就是contract,Illuminate\Contracts\Cache\Repository,因为它只是接口,不需要关心背后是memcache还是redis。

简单性

如果所有服务都使用接口定义,就可以很简单的决定一个服务需要的功能,更加容易维护和扩展,并且contract接口还能看作一个简洁的文档便于阅读。

PHP 相关文章推荐
session 的生命周期是多长
Oct 09 PHP
dedecms系统常用术语汇总
Apr 03 PHP
php 连接mssql数据库 初学php笔记
Mar 01 PHP
PHP函数microtime()用法与说明
Dec 04 PHP
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
Jul 22 PHP
C#静态方法与非静态方法实例分析
Sep 22 PHP
[原创]php集成安装包wampserver修改密码后phpmyadmin无法登陆的解决方法
Nov 23 PHP
PHP将字符串首字母大小写转换的实例
Jan 21 PHP
Laravel Validator自定义错误返回提示消息并在前端展示
May 09 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
Mar 26 PHP
php+mysql实现的无限分类方法类定义与使用示例
May 27 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
Jun 24 PHP
php打印一个边长为N的实心和空心菱型的方法
Mar 02 #PHP
初识laravel5
Mar 02 #PHP
避免Smarty与CSS语法冲突的方法
Mar 02 #PHP
实现PHP+Mysql无限分类的方法汇总
Mar 02 #PHP
Java和PHP在Web开发方面对比分析
Mar 01 #PHP
php中return的用法实例分析
Feb 28 #PHP
php多次include后导致全局变量global失效的解决方法
Feb 28 #PHP
You might like
全国FM电台频率大全 - 7 吉林省
2020/03/11 无线电
使用网络地址转换实现多服务器负载均衡
2006/10/09 PHP
php中日期加减法运算实现代码
2011/12/08 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
学习php设计模式 php实现命令模式(command)
2015/12/08 PHP
Zend Framework教程之前端控制器Zend_Controller_Front用法详解
2016/03/07 PHP
ThinkPHP Where 条件中常用表达式示例(详解)
2017/03/31 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
php/JS实现的生成随机密码(验证码)功能示例
2019/06/06 PHP
xtree.js 代码
2007/03/13 Javascript
使用script的src实现跨域和类似ajax效果
2014/11/10 Javascript
JavaScript 实现完美兼容多浏览器的复制功能代码
2015/04/28 Javascript
jQuery进行组件开发完整实例
2015/12/15 Javascript
深入理解JS DOM事件机制
2016/08/06 Javascript
JS基于递归算法实现1,2,3,4,5,6,7,8,9倒序放入数组中的方法
2017/01/03 Javascript
angularjs实现上拉加载和下拉刷新数据功能
2017/06/12 Javascript
jQuery实现简单的计时器功能实例分析
2017/08/29 jQuery
CheckBox多选取值及判断CheckBox选中是否为空的实例
2017/10/31 Javascript
使用Vue写一个datepicker的示例
2018/01/27 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
javascript sort()对数组中的元素进行排序详解
2019/10/13 Javascript
[57:12]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第一场 10.31
2020/11/02 DOTA
用python处理图片之打开\显示\保存图像的方法
2018/05/04 Python
基于Python中求和函数sum的用法详解
2018/06/28 Python
Django中的Model操作表的实现
2018/07/24 Python
详解pyenv下使用python matplotlib模块的问题解决
2018/11/29 Python
Python测试模块doctest使用解析
2019/08/10 Python
python实现超级马里奥
2020/03/18 Python
英国计算机产品零售商:Novatech(定制个人电脑、笔记本电脑、工作站和服务器)
2018/01/28 全球购物
哈萨克斯坦最大的时装、鞋子和配饰在线商店:Lamoda.kz
2019/11/19 全球购物
如何让Java程序执行效率更高
2014/06/25 面试题
军训自我鉴定200字
2014/02/13 职场文书
医院院务公开实施方案
2014/05/03 职场文书
上课不认真检讨书
2014/09/17 职场文书
党员民主生活会材料
2014/12/15 职场文书
重阳节活动主持词
2015/07/04 职场文书