php设计模式-简单依赖注入容器+自动绑定特性
class C
{
public function sayHello()
{
echo 'I am C';
}
}
class B
{
private $_c;
public function __construct(C $c)
{
$this->_c = $c;
}
public function sayHello()
{
echo 'I am B';
$this->_c->sayHello();
}
}
class A
{
private $_b;
public function __construct(B $b)
{
$this->_b = $b;
}
public function sayHello()
{
echo 'I am A';
$this->_b->sayHello();
}
}
echo '<pre>';
class Container
{
private $_map = array();
public function __set($k, $c)
{
$this->_map[$k] = $c;
}
public function __get($k)
{
if (!isset($this->_map[$k])) throw new Exception('Undefined class');
return $this->build($this->_map[$k]);
}
private function build($classname)
{
if ($classname instanceof Closure) return $classname($this);
$reflection = new ReflectionClass($classname); // 涉及php反射相关知识
// 检查类是否可实例化, 排除抽象类abstract和对象接口interface
if (!$reflection->isInstantiable()) throw new Exception("接口不能被实例化");
if ($reflection === null) throw new Exception('类未定义');
$constructor = $reflection->getConstructor();
if (is_null($constructor)) return new $classname;
if (!$constructor->isPublic()) throw new Exception('类不能被实例化');
$parameters = $constructor->getParameters();
if ($parameters === null) return new $classname;
// 递归解析构造参数
$dependencies = $this->_getDependency($parameters);
// 创建一个类的新实例,给出的参数将传递到类的构造函数。
return $reflection->newInstanceArgs($dependencies);
}
private function _getDependency($parameters)
{
$dependencies = [];
foreach ($parameters as $parameter) {
$dependency = $parameter->getClass();
if (is_null($dependency)) {
$dependencies[] = $this->_resolveClass($parameter);
} else {
$dependencies[] = $this->build($dependency->name);
}
}
return $dependencies;
}
private function _resolveClass($parameter)
{
if ($parameter->isDefaultValueAvailable()) {
return $parameter->getDefaultValue();
}
throw new Exception('Unknow error');
}
}
$di = new Container();
$di->a = 'A';
$di->a->sayHello();
结果:
I am AI am BI am C


浙公网安备 33010602011771号