<?phpclassContainer{protected$bindings=[];// bind用于绑定或者注册服务publicfunctionbind($abstract,$concrete=null,$shared=false){if(!$concreteinstanceofClosure){$concrete=$this->getClosure($abstract,$concrete);}$this->bindings[$abstract]=compact('concrete','shared');}// 为没提供闭包函数的服务提供一个默认的闭包protectedfunctiongetClosure($abstract,$concrete){returnfunction($c)use($abstract,$concrete){$method=($abstract==$concrete)?'build':'make';return$c->$method($concrete);};}// 生成实例publicfunctionmake($abstract){$concrete=$this->getConcrete($abstract);if($this->isBuildable($abstract,$concrete)){return$this->build($concrete);}return$this->make($concrete);}// 生成实例publicfunctionbuild($concrete){if($concreteinstanceofClosure){return$concrete($this);}$reflection=newReflectionClass($concrete);if(!$reflection->isInstantiable()){echo$message='This class is not instantiable !!!!';return;}$constructor=$reflection->getConstructor();if(is_null($constructor)){returnnew$concrete;}$dependencies=$constructor->getParameters();$parameters=$this->resolveDependencies($dependencies);return$reflection->newInstanceArgs($parameters);}// 解决参数依赖protectedfunctionresolveDependencies($parameters){$dependencies=null;foreach($parametersas$parameter){$_cls=$parameter->getClass();if(is_null($_cls)){$dependencies[]=null;}else{$dependencies[]=$this->make($_cls->name);}}return(array)$dependencies;}protectedfunctionisBuildable($abstract,$concrete){return$abstract==$concrete||$concreteinstanceofClosure;}protectedfunctiongetConcrete($abstract){if(!isset($this->bindings[$abstract])){return$abstract;}return$this->bindings[$abstract]['concrete'];}}// test code partInterfaceA{publicfunctiontest();}classBimplementsA{publicfunctiontest(){echo'This is b from A';}}classCimplementsA{publicfunction__construct($name){$this->name=$name;}publicfunctiontest(){echo'This is c from A';}}classD{public$obj;/**
* D constructor.
* @param $obj
*/publicfunction__construct(A$obj){$this->obj=$obj;}publicfunctionrun(){$this->obj->test();}}$app=newContainer();$app->bind('A','C');$app->bind('D','D');$d=$app->make('D');$d->run();