定义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