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