简而言之(因为这不仅仅限于OOP世界), 依赖 就是组件A需要(依赖)组件B来完成应做的工作的情况。该词还用于描述这种情况下的依赖组件。为了用OOP
/ PHP术语来表示,请考虑以下示例,与强制性汽车类比类似:
class Car { public function start() { $engine = new Engine(); $engine->vroom(); }}Car依赖 于
Engine。
Engine是
Car的 依赖 。但是这段代码非常糟糕,因为:
- 依赖关系是隐式的;在检查
Car
的代码之前,您不知道它的存在 - 班级紧密相连;你不能代替
Engine
以MockEngine
用于测试目的或TurboEngine
扩展原有的一个,而无需修改Car
。 - 汽车能够自己制造引擎看起来有点愚蠢,不是吗?
依赖注入 是一种方法,它通过使
Car需要的事实变得
Engine明确并为它提供一个条件来解决所有这些问题:
class Car { protected $engine; public function __construct(Engine $engine) { $this->engine = $engine; } public function start() { $this->engine->vroom(); }}$engine = new SuperDuperTurboEnginePlus(); // a subclass of Engine$car = new Car($engine);上面是 构造函数注入
的示例,其中通过类构造函数将依赖项(被依赖对象)提供给依赖项(消费者)。另一种
setEngine方法是在
Car类中公开一个方法,并使用该方法注入的实例
Engine。这称为“
setter注入” ,主要用于应该在运行时交换的依赖项。
任何不平凡的项目都由一堆相互依赖的组件组成,并且很容易很快就就无法确定注入了什么。一个 依赖注入容器
是一个知道如何实例化和配置其他对象的对象,知道他们与项目的其他对象的关系是并执行依赖注入你。这使您可以集中管理所有项目的(相互)依赖关系,更重要的是,可以更改/模拟一个或多个依赖关系,而不必在代码中编辑很多地方。
让我们抛开汽车类比,以OP试图实现的示例为例。假设我们有一个
Database取决于
mysqli对象的对象。假设我们要使用一个真正原始的依赖项指示符容器类
DIC,该类公开两种方法:
register($name,$callback)以给定名称注册创建对象的方法,并
resolve($name)从该名称获取对象。我们的容器设置如下所示:
$dic = new DIC();$dic->register('mysqli', function() { return new mysqli('somehost','username','password');});$dic->register('database', function() use($dic) { return new Database($dic->resolve('mysqli'));});请注意,我们告诉容器
mysqli从其自身
获取一个实例来组装的实例
Database。然后,要获得一个
Database实例,它的依赖项会自动注入,我们将简单地:
$database = $dic->resolve('database');这就是要旨。Pimple是一个稍微复杂但仍相对简单易懂的PHP DI /
IoC容器。查看其文档以获取更多示例。
关于OP的代码和问题:
- 不要对容器使用静态类或单例(或与此有关的任何其他东西);他们都是邪恶的。请改用Pimple。
- 确定是要 扩展
mysqliWrapper
类还是要 依赖 它。mysql
- 通过
IoC
从内部调用,mysqliWrapper
您可以将一个依赖关系交换为另一个依赖关系。您的对象不应该知道或使用容器;否则,它不再是DIC,而是服务定位器(反)模式。 require
在将文件注册到容器中之前,不需要类文件,因为您根本不知道是否要使用该类的对象。将所有容器设置放在一个地方。如果您不使用自动加载器,则可以require
在向容器注册的匿名函数内部。



