<?phpclassContainer{protected$bindings=[];//绑定接口和生成相应实例的回调函数 "traveller", "Traveller"publicfunctionbind($abstract,$concrete=null,$shared=false){if(!$concreteinstanceofClosure){$concrete=function($c)use($abstract,$concrete){//"traveller", "Traveller"$method=($abstract==$concrete)?'build':'make';return$c->$method($concrete);};}$this->bindings[$abstract]=compact('concrete','shared');}//生成实例对象,首先解决接口和要实例化类之间的依赖关系 "traveller" "Traveller"publicfunctionmake($abstract){if(!isset($this->bindings[$abstract])){return$this->build($abstract);}else{$concrete=$this->bindings[$abstract]['concrete'];}if($concreteinstanceofClosure){$object=$this->build($concrete);}else{$object=$this->make($concrete);}return$object;}// 实例化对象publicfunctionbuild($concrete){if($concreteinstanceofClosure){return$concrete($this);}$reflector=newReflectionClass($concrete);if(!$reflector->isInstantiable()){echo$message="Target [$concrete] is not instantiable.";}$constructor=$reflector->getConstructor();if(is_null($constructor)){returnnew$concrete;}$dependencies=$constructor->getParameters();$instances=$this->getDependencies($dependencies);return$reflector->newInstanceArgs($instances);}//解决通过放射机制实例化对象时的依赖protectedfunctiongetDependencies($parameters){$dependencies=[];foreach($parametersas$parameter){$dependency=$parameter->getClass();if(is_null($dependency)){$dependencies[]=NULL;}else{$name=$parameter->getClass()->name;$class=$this->make($name);$dependencies[]=$class;}}return(array)$dependencies;}}
使用
interfaceVisit{publicfunctiongo();}classTrainimplementsVisit{publicfunctiongo(){echo"go to Tibet by train!!!";}}classTraveller{protected$trafficTool;publicfunction__construct(Visit $trafficTool){$this->trafficTool=$trafficTool;}publicfunctionvisitTibet(){$this->trafficTool->go();}}//实例化Ioc容器$app=newContainer();//完成容器的填充$app->bind('Visit','Train');$app->bind("traveller","Traveller");//通过容器实现依赖注入,完成类的实例化$tra=$app->make("traveller");$tra->visitTibet();