项目源码
功能实现
- 解决类重复依赖创建、解决相互依赖(A->B->A->B->...)、循环依赖(A->B->C->A->B->C->A->...)
/**
* 解决相互依赖及循环依赖判断
* @param string $abstract
* @param array $tmp
* @return Closure|object
* @throws ReflectionException
*/
public function createObjectNoEach(string $abstract, array $tmp = [])
{
if ($tmpInstance = &$tmp[$abstract]) {
return $tmpInstance;
}
$refClass = new ReflectionClass($abstract);
if ($refClass->getName() === Closure::class) {
return function (){};
} elseif ($refClass->hasMethod('__construct')) {
$_constructParams = array_map(function (ReflectionParameter $param) use ($abstract, $tmp) {
if ($param->getClass()) {
if (array_key_exists($param->getClass()->getName(), $tmp)) {
throw new class('can not create a circular dependencies class object.') extends Exception implements ContainerExceptionInterface{ };
}
return $this->createObjectNoEach($param->getClass()->getName(), $tmp);
} elseif ($param->isDefaultValueAvailable()) {
return $param->getDefaultValue();
} elseif ($param->getType()) {
return [
'string' => '',
'int' => 0,
'array' => [],
'bool' => false,
'float' => 0.0,
'iterable' => [],
'callable' => function() {}
][$param->getType()->getName()] ?? null;
} else {
return null;
}
}, $refClass->getMethod('__construct')->getParameters());
}
return $tmpInstance = $refClass->newInstance(... ($_constructParams ?? []));
}
实现思路
- 通过存储自动创建实例对象,在参数列表中出现相同的类时判断为循环并抛出异常
添加代码
- 判断是否缓存有实例对象
if ($tmpInstance = &$tmp[$abstract]) {
return $tmpInstance;
}
- 判断自动创建的类是否被创建过,如果被创建过则认为是递归,抛出异常
if (array_key_exists($param->getClass()->getName(), $tmp)) {
throw new class('can not create a circular dependencies class object.') extends Exception implements ContainerExceptionInterface{ };
}
return $this->createObjectNoEach($param->getClass()->getName(), $tmp);
- 存储自动创建的类实例
return $tmpInstance = $refClass->newInstance(... ($_constructParams ?? []));
注
示例
网友评论