stubbles / ioc
依赖注入。
Requires
- php: ^8.2
- stubbles/reflect: ^10.0
- stubbles/sequence: ^10.1
- stubbles/values: ^11.0
Requires (Dev)
- bovigo/assert: ^8.0
- bovigo/callmap: ^8.0
- mikey179/vfsstream: ^1.6.11
- phpunit/phpunit: ^10.5
- stubbles/streams: ^10.0
- dev-main / 11.0.x-dev
- v11.0.0
- v10.2.0
- v10.1.0
- v10.0.0
- v9.0.0
- v8.0.1
- v8.0.0
- v7.1.1
- v7.1.0
- v7.0.0
- v6.3.0
- v6.2.0
- v6.1.0
- v6.0.0
- v5.5.1
- v5.5.0
- v5.4.1
- v5.4.0
- v5.3.2
- v5.3.1
- v5.3.0
- v5.2.0
- v5.1.2
- v5.1.1
- v5.1.0
- v5.0.1
- v5.0.0
- v4.1.4
- v4.1.3
- v4.1.2
- v4.1.1
- v4.1.0
- v4.0.2
- v4.0.1
- v4.0.0
- v3.5.3
- v3.5.2
- v3.5.1
- v3.5.0
- v3.4.4
- v3.4.3
- v3.4.2
- v3.4.1
- v3.4.0
- v3.3.1
- v3.3.0
- v3.2.0
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.0
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.0
- v2.0.0-beta8
- 2.0.0-beta7
- 2.0.0-beta6
- 2.0.0-beta5
- 2.0.0-beta4
- 2.0.0-beta2
- 2.0.0-beta1
- dev-dependabot/composer/phpunit/phpunit-10.5.24
This package is auto-updated.
Last update: 2024-08-31 12:15:24 UTC
README
依赖注入。
构建状态
安装
stubbles/ioc 以 Composer 包的形式分发。要将它作为您的包的依赖项安装,请使用以下命令
composer require "stubbles/ioc": "^11.0"
需求
stubbles/ioc 至少需要 PHP 8.2。
控制反转
stubbles/ioc 提供了一个非常简单易用但功能强大的 控制反转容器,它支持基于构造函数和设置器的依赖注入。 stubbles/ioc 的 IoC 容器模仿了 Google Guice 并使用类型提示注解。如果您从未听说过类型提示或注解,您应首先阅读关于这两个主题的章节
- PHP 手册中关于 '类型提示' 的章节
- 注解 stubbles/reflect 中关于注解的章节。
示例代码
想象一下,您正在构建一个汽车配置器。为了遵循良好的设计原则,您为汽车的所有组件定义了接口,并提供了一些实现这些组件的类。
您应用程序中的接口包括
interface Car { public function moveForward($miles); } interface Person { public function sayHello(); } interface Tire { public function rotate(); } interface Engine { public function start(); }
实现包括
class BMW implements Car { private $driver; private $engine; private $tire; public function __construct(Engine $engine, Tire $tire, Person $driver) { $this->engine = $engine; $this->tire = $tire; $this->driver = $driver; } public function moveForward($miles) { $this->driver->sayHello(); $this->engine->start(); $this->tire->rotate(); } } class Schst implements Person { public function sayHello() { echo "My name is Stephan\n"; } } class Goodyear implements Tire { public function rotate() { echo "Rotating Goodyear tire\n"; } } class TwoLitresEngine implements Engine { public function start() { echo "Starting 2l engine\n"; } }
没有依赖注入框架
要创建 Car
实现的一个新实例,需要以下代码
$tire = new Goodyear(); $engine = new TwoLitresEngine(); $schst = new Schst(); $bmw = new BMW($engine, $tire, $schst); $bmw->moveForward(50);
手动创建对象如这种方式有几个缺点
- 您的应用程序绑定到具体的实现,而不是接口
- 更改实现意味着更改现有代码,这可能会破坏它
- 对象的创建散布在您的应用程序中
当然,真实的应用程序有更多类,所以事情只会变得更糟。
进入 '控制反转'
stubbles/ioc 通过提供处理所有依赖注入的功能来尝试解决这些问题,这使得您的应用程序没有样板代码。
此外,它允许您集中定义或模块化接口或抽象类型的具体实现。
简单示例
定义具体实现是通过 stubbles\ioc\Binder
的一个实例来完成的
$binder = new \stubbles\ioc\Binder(); $binder->bind('Car')->to('BMW'); $binder->bind('Tire')->to('Goodyear'); $binder->bind('Person')->to('Schst'); $binder->bind('Engine')->to('TwoLitresEngine');
在这段简短的代码片段中,您将上面示例中的接口绑定到它们的具体实现。
如果您现在需要一个引擎的实例,您可以使用绑定器创建一个 stubbles\ioc\Injector
,它可以用来创建所需的 Engine
$injector = $binder->getInjector(); $engine = $injector->getInstance('Engine'); var_dump($engine);
现在这段代码片段将显示
object(TwoLitresEngine)#48 (0) {
}
正如预期的那样,它创建了一个具体实现的实例,您将其绑定到接口。
接下来,您可能还想用相同的方法获取 Car
的实例
$injector = $binder->getInjector(); $car = $injector->getInstance('Car'); var_dump($car);
object(BMW)#33 (3) {
["driver:private"]=>
NULL
["engine:private"]=>
object(TwoLitresEngine)#37 (0) {
}
["tire:private"]=>
object(Goodyear)#40 (0) {
}
}
stubbles/ioc 创建了一个新的 BMW
实例,因为您将其绑定到 Car
,并且因为 BMW
的构造函数需要一个 Tire
和一个 Engine
实例,所以它也创建了这些实例。为了确定要使用的具体类,stubbles/ioc 使用了您在 stubbles\ioc\Binder
实例中定义的绑定。
你还可以看到,尽管你为Person
指定了绑定,但Stubbles并没有将对象注入到$driver
属性中。stubbles/ioc将永远不会通过setter方法注入任何依赖。