定义Demo类
<?php
class C
{
public function doSomething() {
echo __METHOD__, '我是C类<br />';
}
}
class B
{
private $c;
public function __construct(C $c) {
$this->c = $c;
}
public function doSomething() {
$this->c->doSomething();
echo __METHOD__, '我是B类<br />';
}
}
class A
{
private $b;
private $d;
public function __construct(B $b, $d) {
$this->b = $b;
$this->d = $d;
}
public function doSomething() {
$this->b->doSomething();
echo __METHOD__, '我是A类<br />';
echo $this->d;
}
} 依赖注入实现:
/************************ 依赖注入 Start *************************
class YiLaiZhuRu
{
private $s = array();
function __set($k, $c)
{
$this->s[$k] = $c;
}
function __get($k)
{
return $this->s[$k]($this);
}
}
echo '依赖注入:<br/>';
$class = new YiLaiZhuRu();
$class->c = function() {
return new C();
};
$class->b = function($class) {
return new B($class->c);
};
$class->a = function($class) {
return new A($class->b);
};
$class->a->doSomething();
/************************ 依赖注入 End *************************/
容器实现:
/************************ 容器 Start *************************
class Ioc
{
protected static $register = array();
public static function bind($name, Callable $callback)
{
static::$register[$name] = $callback;
}
public static function make($name)
{
if (isset(static::$register[$name])) {
$callback = static::$register[$name];
return $callback();
}
}
}
echo '<br />容器:<br/>';
Ioc::bind('c', function()
{
return new C();
});
Ioc::bind('b', function()
{
return new B(Ioc::make('c'));
});
Ioc::bind('a', function()
{
return new A(Ioc::make('b'));
});
Ioc::make('a')->doSomething();
/************************ 容器 End *************************/
高级容器实现
/************************ 高级容器 Start *************************/
/**
* 依赖注入容器的高级功能
* 真实的dependency injection container会提供更多的特性,如
* 自动绑定(AutoWiring)或 自动解析(Automatic Resolution)
* 注释解析器(Annotations)
* 延迟注入(Lazy injection)
*/
class Container
{
private $register = array();
private $params = array();
public function __set($k, $c)
{
if (is_string($c)) {
$this->register[$k] = $c;
$this->params[$k] = [];
} elseif (is_array($c)) {
$this->register[$k] = $c['class'];
$this->params[$k] = $c['param'];
}
}
public function __get($k)
{
try {
return $this->build($this->register[$k], $this->params[$k]);
}
catch (exception $e) {
dump($e);
}
}
/**
* 自动绑定(Autowiring)自动解析(Automatic Resolution)
*
* @param string $className
* @param string $classParam
* @return object
* @throws Exception
*/
public function build($className, $classParam = [])
{
// 如果是匿名函数(Anonymous functions),也叫闭包函数(closures)
if ($className instanceof Closure) {
// 执行闭包函数,并将结果
return $className($this);
}
/** @var ReflectionClass $reflector */
$reflector = new ReflectionClass($className);
// 检查类是否可实例化, 排除抽象类abstract和对象接口interface
if (!$reflector->isInstantiable()) {
throw new Exception("Can't instantiate this.");
}
/** @var ReflectionMethod $constructor 获取类的构造函数 */
$constructor = $reflector->getConstructor();
// 若无构造函数,直接实例化并返回
if (is_null($constructor)) {
return new $className;
}
// 取构造函数参数,通过 ReflectionParameter 数组返回参数列表
$parameters = $constructor->getParameters();
// 递归解析构造函数的参数
$dependencies = $this->getDependencies($parameters, $classParam);
// 创建一个类的新实例,给出的参数将传递到类的构造函数。
return $reflector->newInstanceArgs($dependencies);
}
/**
* @param array $parameters
* @return array
* @throws Exception
*/
public function getDependencies($parameters, $classParam = [])
{
$dependencies = [];
/** @var ReflectionParameter $parameter */
foreach ($parameters as $parameter) {
/** @var ReflectionClass $dependency */
$dependency = $parameter->getClass();
if (is_null($dependency)) {
// 是变量,有默认值则设置默认值
$dependencies[] = $this->resolveNonClass($parameter, $classParam);
} else {
// 是一个类,递归解析
$dependencies[] = $this->build($dependency->name);
}
}
return $dependencies;
}
/**
* @param ReflectionParameter $parameter
* @return mixed
* @throws Exception
*/
public function resolveNonClass($parameter, $classParam)
{
// 有默认值则返回默认值
if ($parameter->isDefaultValueAvailable()) {
return $parameter->getDefaultValue();
} elseif ($classParam[$parameter->getName()]) {
return $classParam[$parameter->getName()];
}
throw new Exception('I have no idea what to do here.');
}
}
echo '<br />高级容器:</br />';
$di = new Container();
// $di->a = 'A';
$di->a = [
'class' => 'A',
'param' => [
'd' => function() {echo 1;}
]
];
$model = $di->a;
$model->doSomething();
/************************ 高级容器 End *************************/
来源:原创
发布时间:2022-07-13 12:27:03