这篇文章主要介绍了PHP依赖注入(DI)和控制反转(IoC)的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些力量。

首先先别追究这个设计模式的定义,否则你一定会被说的云里雾里,笔者就是深受其害,百度了N多文章,都是从理论角度来描述,充斥着大量的生涩词汇,要么就是java代码描述的,也生涩。

不管怎么样,总算弄清楚一些了,下面就以php的角度来描述一下依赖注入这个概念。

先假设我们这里有一个类,类里面需要用到数据库连接,按照最最原始的办法,我们可能是这样写这个类的:

1
2
3
4
5
6
7
8
9
10
11
class example {
   
  private $_db;
  function __construct(){
    include "./Lib/Db.php";
    $this->_db = new Db("localhost","root","123456","test");
  }
  function getList(){
    $this->_db->query("......");//这里具体sql语句就省略不写了
  }
 }

过程:

在构造函数里先将数据库类文件include进来;
然后又通过new Db并传入数据库连接信息实例化db类;
之后getList方法就可以通过$this->_db来调用数据库类,实现数据库操作。

看上去我们实现了想要的功能,但是这是一个噩梦的开始,以后example1,example2,example3....越来越多的类需要用到db组件,如果都这么写的话,万一有一天数据库密码改了或者db类发生变化了,岂不是要回头修改所有类文件?
ok,为了解决这个问题,工厂模式出现了,我们创建了一个Factory方法,并通过Factory::getDb()方法来获得db组件的实例:

1
2
3
4
5
6
class Factory {
  public static function getDb(){
    include "./Lib/Db.php";
    return new Db("localhost","root","123456","test");
  }
 }

sample类变成:

1
2
3
4
5
6
7
8
9
10
class example {
   
  private $_db;
  function __construct(){
    $this->_db = Factory::getDb();
  }
  function getList(){
    $this->_db->query("......");//这里具体sql语句就省略不写了
  }
 }

这样就完美了吗?再次想想一下以后example1,example2,example3....所有的类,你都需要在构造函数里通过Factory::getDb();获的一个Db实例,实际上你由原来的直接与Db类的耦合变为了和Factory工厂类的耦合,工厂类只是帮你把数据库连接信息给包装起来了,虽然当数据库信息发生变化时只要修改Factory::getDb()方法就可以了,但是突然有一天工厂方法需要改名,或者getDb方法需要改名,你又怎么办?当然这种需求其实还是很操蛋的,但有时候确实存在这种情况,一种解决方式是:

我们不从example类内部实例化Db组件,我们依靠从外部的注入,什么意思呢?看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class example {
  private $_db;
  function getList(){
    $this->_db->query("......");//这里具体sql语句就省略不写了
  }
  //从外部注入db连接
  function setDb($connection){
    $this->_db = $connection;
  }
 }
 //调用
$example = new example();
$example->setDb(Factory::getDb());//注入db连接
$example->getList();

这样一来,example类完全与外部类解除耦合了,你可以看到Db类里面已经没有工厂方法或Db类的身影了。我们通过从外部调用example类的setDb方法,将连接实例直接注入进去。这样example完全不用关心db连接怎么生成的了。
这就叫依赖注入,实现不是在代码内部创建依赖关系,而是让其作为一个参数传递,这使得我们的程序更容易维护,降低程序代码的耦合度,实现一种松耦合。

这还没完,我们再假设example类里面除了db还要用到其他外部类,我们通过:

1
2
3
4
$example->setDb(Factory::getDb());//注入db连接
$example->setFile(Factory::getFile());//注入文件处理类
$example->setImage(Factory::getImage());//注入Image处理类
 ...

我们没完没了的写这么多set?累不累?
ok,为了不用每次写这么多行代码,我们又去弄了一个工厂方法:

1
2
3
4
5
6
7
8
9
class Factory {
  public static function getExample(){
    $example = new example();
    $example->setDb(Factory::getDb());//注入db连接
    $example->setFile(Factory::getFile());//注入文件处理类
    $example->setImage(Factory::getImage());//注入Image处理类
    return $expample;
  }
 }

实例化example时变为:

1
2
$example=Factory::getExample();
$example->getList();

似乎完美了,但是怎么感觉又回到了上面第一次用工厂方法时的场景?这确实不是一个好的解决方案,所以又提出了一个概念:容器,又叫做IoC容器、DI容器。

我们本来是通过setXXX方法注入各种类,代码很长,方法很多,虽然可以通过一个工厂方法包装,但是还不是那么爽,好吧,我们不用setXXX方法了,这样也就不用工厂方法二次包装了,那么我们还怎么实现依赖注入呢?
这里我们引入一个约定:在example类的构造函数里传入一个名为Di $di的参数,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class example {
  private $_di;
  function __construct(Di &$di){
    $this->_di = $di;
  }
  //通过di容器获取db实例
  function getList(){
    $this->_di->get('db')->query("......");//这里具体sql语句就省略不写了
  }
 }
$di = new Di();
$di->set("db",function(){
  return new Db("localhost","root","root","test");
 });
$example = new example($di);
$example->getList();

Di就是IoC容器,所谓容器就是存放我们可能会用到的各种类的实例,我们通过$di->set()设置一个名为db的实例,因为是通过回调函数的方式传入的,所以set的时候并不会立即实例化db类,而是当$di->get('db')的时候才会实例化,同样,在设计di类的时候还可以融入单例模式。

这样我们只要在全局范围内申明一个Di类,将所有需要注入的类放到容器里,然后将容器作为构造函数的参数传入到example,即可在example类里面从容器中获取实例。当然也不一定是构造函数,你也可以用一个 setDi(Di $di)的方法来传入Di容器,总之约定是你制定的,你自己清楚就行。

这样一来依赖注入以及关键的容器概念已经介绍完毕,剩下的就是在实际中使用并理解它吧!

PHP依赖注入(DI)和控制反转(IoC)详解的更多相关文章

  1. 依赖注入(DI)和控制反转(IOC)

    依赖注入(DI)和控制反转(IOC) 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只 ...

  2. 依赖注入(DI)和控制反转(IOC)的理解,写的太好了。

    学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  3. 【串线篇】依赖注入DI与控制反转IOC

    DI&IOC 在spring框架中DI与IOC说的其实是一回事 一句话:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象. 也就是说我对对象的『依赖』是注入进来的,而和 ...

  4. 轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)

    前言 关于这个话题, 网上有很多文章,这里, 我希望通过最简单的话语与大家分享. 依赖注入和控制反转两个概念让很多初学这迷惑, 觉得玄之又玄,高深莫测. 这里想先说明两点: 依赖注入和控制反转不是高级 ...

  5. 话说 依赖注入(DI) or 控制反转(IoC)

    科普:首先依赖注入和控制反转说的是同一个东西,是一种设计模式,这种设计模式用来减少程序间的耦合,鄙人学习了一下,看TP官网还没有相关的文章,就写下这篇拙作介绍一下这种设计模式,希望能为TP社区贡献一些 ...

  6. ASP.NET MVC进阶之路:深入理解依赖注入(DI)和控制反转(IOC)

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  7. PHP 依赖注入(DI) 和 控制反转(IoC)

    要想理解 PHP 依赖注入 和 控制反转 两个概念,就必须搞清楚如下的两个问题: DI —— Dependency Injection 依赖注入 IoC —— Inversion of Control ...

  8. 聊一聊PHP的依赖注入(DI) 和 控制反转(IoC)

    简介 IoC Inversion of Control 控制反转DI Dependency Injection 依赖注入 依赖注入和控制反转说的实际上是同一种东西,它们是一种设计模式,这种设计模式用来 ...

  9. 依赖注入(DI)与控制反转(IOC)

    DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,Inversion of Control )是一个意思. DI是一种通过接口实现松耦合的设计模式.初学者可能会好奇 ...

随机推荐

  1. sublime 自动添加兼容前缀插件autoprefixer

    安装插件autoprefixer步骤: 1.确保Node.js已经安装,未安装请 点击 这里>> 2.下载autoprefixer插件 https://github.com/sindres ...

  2. oracel SQL多表查询优化

    SQL优化 1.执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只要0.02秒,但是2张表联合统计就 ...

  3. Linux下的Nginx部署禅道

    基本思路:先安装好nginx和mysql和php,上传禅道的源码.把禅道的源码包扔到 nginx/apache 的工程路径内或者nginx/apache内的配置文件指向nginx的路径,然后将ngin ...

  4. 如何生成SPFILE文件

    1.spfile是Oracle9i之后引入的,目的是提高系统安全性.在Oracle8i下初始化参数文件为文本文件,可以使用文本编辑器进行编辑,当需要修改初始化参数时,需要在init.ora文件中修改, ...

  5. Java中 @Override 的作用

    @Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处: 可以当注释用,方便阅读: 编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错.例如,你如 ...

  6. Map 的营救;使对象属性有顺序

    使用ES6的新特性Map.Map 对象以插入的顺序遍历元素.for...of循环为每一次循环返回一个[key, value]数组. 如果想在跨浏览器环境中模拟一个有序的关联数组,你要么使用两个分开的数 ...

  7. FineUI与百度地图简单示例 (转帖)

    http://www.fineui.com/bbs/forum.php?mod=viewthread&tid=4191&extra=page%3D1 前台代码 <%@ Page ...

  8. 【jmeter】jmeter之-断言和检查点

    断言就类似LoadRunner中的检查点.对上一个请求返回的信息,做字符串.数据包大小.HTML.XML.图片等做判断,确保返回的信息的准确性. 简单的来理解一下,上一章讲到,我们对用户名和密码进行了 ...

  9. SEO之H1,H2,H3,H4....STRONG使用方法

    作为一个SEO从业人员,我们不仅仅是要懂得如何通过网站内容和外链等SEO手段,其实一个优秀的SEOER在从事一个SEO案例时,首先着手的是如何从网站程序本身来打好网站SEO基础. 在平时和很多朋友的交 ...

  10. TX Textcontrol 使用总结一模板

    以下内容纯属个人使用感想,如有问题,还望讲解!!! 简介与使用感想: TX Text Control是一套功能丰富的文字处理控件,它以可重复使用控件的形式为开发人员提供了Word中常用的文字处理功能, ...