PHP IOC容器

匿名 (未验证) 提交于 2019-12-02 22:11:45

简单得容器:

class SomeComponent{     protected $_connection;      public function setConnection($connection){         $this->_connection = $connection;     }      public function getConnection($connection){         return $this->_connection;     } }

这个案例可以实现我们在外部注入到SomeComponent类中,不过这样不好得就是只能写一个实例,

class SomeComponent{     protected $_connection;      public function setConnection($key, $connection){         $this->_connection[$key] = $connection;     }      public function getConnection($key){         if( isset( $this->_connection[$key] ) ){             return $this->_connection[$key]         }else{             throw new Exception("class not exist", 1);          }     } }

这个例子可以实现多个类注入到里面,但是不好得就是得手动实例化类。
laravel中得依赖注入容器(里面主要用到得技术:反射,依赖注入,闭包):

//容器类装实例或提供实例的回调函数 class Container {      //用于装提供实例的回调函数,真正的容器还会装实例等其他内容     //从而实现单例等高级功能     protected $bindings = [];      //绑定接口和生成相应实例的回调函数     public function bind($abstract, $concrete=null, $shared=false) {          //如果提供的参数不是回调函数,则产生默认的回调函数         if(!$concrete instanceof Closure) {             $concrete = $this->getClosure($abstract, $concrete);         }          $this->bindings[$abstract] = compact('concrete', 'shared');     }      //默认生成实例的回调函数     protected 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;     }      protected function isBuildable($concrete, $abstract) {         return $concrete === $abstract || $concrete instanceof Closure;     }      //获取绑定的回调函数     protected function getConcrete($abstract) {         if(!isset($this->bindings[$abstract])) {             return $abstract;         }          return $this->bindings[$abstract]['concrete'];     }      //实例化对象     public function build($concrete) {          if($concrete instanceof Closure) {             return $concrete($this);         }          $reflector = new ReflectionClass($concrete);         if(!$reflector->isInstantiable()) {             echo $message = "Target [$concrete] is not instantiable";         }          $constructor = $reflector->getConstructor();         if(is_null($constructor)) {             return new $concrete;         }          $dependencies = $constructor->getParameters();         $instances = $this->getDependencies($dependencies);          return $reflector->newInstanceArgs($instances);     }      //解决通过反射机制实例化对象时的依赖     protected function getDependencies($parameters) {         $dependencies = [];         foreach($parameters as $parameter) {             $dependency = $parameter->getClass();             if(is_null($dependency)) {                 $dependencies[] = NULL;             } else {                 $dependencies[] = $this->resolveClass($parameter);             }         }          return (array)$dependencies;     }      protected function resolveClass(ReflectionParameter $parameter) {         return $this->make($parameter->getClass()->name);     }  }

上面的代码就生成了一个容器,下面是如何使用容器

$app = new Container(); $app->bind("Pay", "Alipay");//Pay 为接口, Alipay 是 class Alipay $app->bind("tryToPayMyBill", "PayBill"); //tryToPayMyBill可以当做是Class PayBill 的服务别名  //通过字符解析,或得到了Class PayBill 的实例 $paybill = $app->make("tryToPayMyBill");   //因为之前已经把Pay 接口绑定为了 Alipay,所以调用pay 方法的话会显示 'pay bill by alipay ' $paybill->payMyBill(); 

参考文章:链接地址

文章来源: PHP IOC容器
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!