<?php interface Animal{ public function attack(); public function talk(); } class People implements Animal{ public $month; public $hand; public function __construct(Mouth $mouth,Hand $hand) { $this->month = $mouth; $this->hand = $hand; } public function attack() { $this->hand->scrap(); } public function talk() { $this->month->say(); } } class Mouth{ public function say(){ echo "咿咿呀呀"; }}class Hand{ public $finger; public function __construct(Finger $finger) { $this->finger = $finger; } public function scrap(){ echo ‘仍玩具‘; } public function otherFunction(){ $this->finger->eatFinger(); }} class Finger{ public function eatFinger(){ echo "吃手指"; }} class Container{ /** * 容器绑定,用来装提供的实例或者 提供实例的回调函数 * @var array */ public $building = []; /** * 注册一个绑定到容器 */ public function bind($abstract, $concrete = null, $shared = false){ if(is_null($concrete)){ $concrete = $abstract; } if(!$concrete instanceOf Closure){ $concrete = $this->getClosure($abstract, $concrete); } $this->building[$abstract] = compact("concrete", "shared");} //注册一个共享的绑定 单例 public function singleton($abstract, $concrete, $shared = true){ $this->bind($abstract, $concrete, $shared);} /** * 默认生成实例的回调闭包 * * @param $abstract * @param $concrete * @return Closure */ public function getClosure($abstract, $concrete){ return function($c) use($abstract, $concrete){ $method = ($abstract == $concrete)? ‘build‘ : ‘make‘; return $c->$method($concrete); };} /** * 生成实例 */ public function make($abstract){ $concrete = $this->getConcrete($abstract); if($this->isBuildable($concrete, $abstract)){ $object = $this->build($concrete); }else{ $object = $this->make($concrete); } return $object;} /** * 获取绑定的回调函数 */ public function getConcrete($abstract){ if(! isset($this->building[$abstract])){ return $abstract; } return $this->building[$abstract][‘concrete‘];} /** * 判断 是否 可以创建服务实体 */ public function isBuildable($concrete, $abstract){ return $concrete === $abstract || $concrete instanceof Closure; } /** * 根据实例具体名称实例具体对象 */ public function build($concrete){ if($concrete instanceof Closure){ return $concrete($this); } //创建反射对象 $reflector = new ReflectionClass($concrete);//通过反射获取类名 if( ! $reflector->isInstantiable()){ //抛出异常 throw new \Exception(‘无法实例化‘); } $constructor = $reflector->getConstructor();//获取构造函数 if(is_null($constructor)){ return new $concrete; } $dependencies = $constructor->getParameters();//获取构造函数参数 $instance = $this->getDependencies($dependencies); return $reflector->newInstanceArgs($instance);//将参数注入到对象中 } //通过反射解决参数依赖 public function getDependencies(array $dependencies){ $results = []; foreach( $dependencies as $dependency ){ $results[] = is_null($dependency->getClass()) ?$this->resolvedNonClass($dependency) :$this->resolvedClass($dependency); } return $results;} //解决一个没有类型提示依赖 public function resolvedNonClass(ReflectionParameter $parameter) { if($parameter->isDefaultValueAvailable()){ return $parameter->getDefaultValue(); } throw new \Exception(‘出错‘); } //通过容器解决依赖 public function resolvedClass(ReflectionParameter $parameter) { return $this->make($parameter->getClass()->name); } }//实例化容器类$container = new Container();$container->bind(‘Animal‘,‘People‘);//将需要创建对象的类放到容器中$people = $container->make(‘Animal‘);//创建对象$people->attack();//调用方法$people->talk();
原文地址:https://www.cnblogs.com/paulversion/p/11703522.html
时间: 2024-10-12 15:10:01