<?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,$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();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。