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 相关文章推荐
POSIX 风格和兼容 Perl 风格两种正则表达式主要函数的类比(preg_match, preg_replace, ereg, ereg_replace)
Oct 12 PHP
PHP中使用foreach和引用导致程序BUG的问题介绍
Sep 05 PHP
关于mysql字符集设置了character_set_client=binary 在gbk情况下会出现表描述是乱码的情况
Jan 06 PHP
ThinkPHP框架实现session跨域问题的解决方法
Jul 01 PHP
PHP将字符分解为多个字符串的方法
Nov 22 PHP
php根据用户语言跳转相应网页
Nov 04 PHP
PHP表单数据写入MySQL数据库的代码
May 31 PHP
Yii2创建控制器(createController)方法详解
Jul 23 PHP
Windows下php+mysql5.7配置教程
May 16 PHP
深入理解PHP的远程多会话调试
Sep 21 PHP
原生JS实现Ajax通过POST方式与PHP进行交互的方法示例
May 12 PHP
Yii2.0实现的批量更新及批量插入功能示例
Jan 29 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
聊天室php&amp;mysql(一)
2006/10/09 PHP
pdo中使用参数化查询sql
2011/08/11 PHP
适用于初学者的简易PHP文件上传类
2015/10/29 PHP
PHP简单操作MongoDB的方法(安装及增删改查)
2016/05/26 PHP
PHP自定义函数获取URL中一级域名的方法
2016/08/23 PHP
ie 调试javascript的工具
2009/04/29 Javascript
子窗口、父窗口和Silverlight之间的相互调用
2010/08/16 Javascript
JavaScript OOP面向对象介绍
2010/12/02 Javascript
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
php 中序列化和json使用介绍
2013/07/08 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
2016/01/18 Javascript
第二篇Bootstrap起步
2016/06/21 Javascript
jQuery删除当前节点元素
2016/12/07 Javascript
JS复制对应id的内容到粘贴板(Ctrl+C效果)
2017/01/23 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
AngularJS 购物车全选/取消全选功能的实现方法
2017/08/14 Javascript
nodeJS服务器的创建和重新启动的实现方法
2018/05/12 NodeJs
JavaScript图像放大镜效果实现方法详解
2020/06/28 Javascript
Pthon批量处理将pdb文件生成dssp文件
2015/06/21 Python
Python常见格式化字符串方法小结【百分号与format方法】
2016/09/18 Python
Python中对数组集进行按行打乱shuffle的方法
2018/11/08 Python
python版飞机大战代码分享
2018/11/20 Python
Python除法之传统除法、Floor除法及真除法实例详解
2019/05/23 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
HTML5 video标签(播放器)学习笔记(二):播放控制
2015/04/24 HTML / CSS
HUGO BOSS美国官方网上商店:世界知名奢侈品牌
2017/08/04 全球购物
兰蔻英国官网:Lancome英国
2019/04/30 全球购物
Flesh Beauty官网:露华浓集团旗下彩妆品牌
2021/02/15 全球购物
C++面试题目
2013/06/25 面试题
党员批评与自我批评
2014/02/12 职场文书
党员入党表决心的话
2014/03/11 职场文书
班主任工作经验交流材料
2014/05/13 职场文书
农业开发项目建议书
2014/05/16 职场文书
授权委托书公证
2014/09/14 职场文书
正风肃纪查摆剖析材料
2014/10/10 职场文书
小学工作总结2015
2015/05/04 职场文书