php反射和laravel依赖注入
2019-04-04 17:56
676 查看
什么是依赖注入?
耦合性很强的例子:
class A { public function __construct() { // A类的内部,依赖了B类 $this->b = new B(); } public function printStrA(){ $this->b->printStrB(); } } class B{ public function __construct() { } public function printStrB(){ echo 'this is string'; } } $obj = new A; $obj->printStrA();
耦合性较弱的例子,传入对象当参数,这就是依赖注入.
<?php class A { public function __construct(B $par) { $this->b = $par; } public function printStrA(){ $this->b->printStrB(); } } class B{ public function __construct() { } public function printStrB(){ echo 'this is string'; } } $obj = new A(new B()); $obj->printStrA();
laravel中通过依赖注入和反射来完成功能.
下面这个例子介绍下反射类
class Test{ public function __construct(Persona $p1, Personb $p2) { echo $p1->printStr()," ",$p2->printStr()," "; } function printString(){ echo 'test'; return; } } class Persona { function printStr() { echo 'persona'; } } class Personb { function printStr(){ echo 'personb'; } } $obj = new Test(new Persona(), new Personb()); //下面是反射 $reflector = new ReflectionClass('Test');// 可以是Test或者$obj作为参数 $constructor = $reflector->getConstructor(); $dependencies = $constructor->getParameters();// 获取构造器里面的参数 $parArr = array(); foreach ($dependencies as $depend){ // $depend->getClass()->name 获取类名称 $className=$depend->getClass()->name; $parArray[] = new $className(); } $refNewObj = $reflector->newInstanceArgs($parArray); $refNewObj->printString();
下面这个是对laravel简化的,实现了容器完成依赖注入.
interface Visit{ public function go(); } class Leg implements Visit{ public function go(){echo 'leg';} } class Car implements Visit{ public function go(){echo 'car';} } class Train implements Visit{ public function go(){echo 'train';} } 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){ //生成实例的回调函数,$c一般为Ioc容器对象,在调用回调生成实例时提供 //既build函数中的$concrete($this) return function($c) use ($abstract,$concrete){ $method=($abstract==$concrete)?'build':'make'; //调用的是容器的build或make方法生成实例 return $c->$method($concrete); }; } //生成实例对象,首先解决接口和要实例化类之间的依赖关系 public function make($abstract){ $concrete=$this->getConcrete($abstract);echo "<pre>";var_dump($abstract)."<hr>"; 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="Traget [$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); } } class Traveller{ protected $trafficTool; public function __construct(Visit $trafficTool){ $this->trafficTool=$trafficTool; } public function visitTibet(){ $this->trafficTool->go(); } } //实例化Ioc容器 $app=new Container(); //完成容器的填充 $app->bind("Visit","Train");; $app->bind("traveller","Traveller"); //通过容器实例依赖注入,完成类的实例化 $tra=$app->make("traveller"); $tra->visitTibet(); die;
后续补充laravel代码的依赖注入…
相关文章推荐
- laravel中如何利用反射实现依赖注入
- PHP实现依赖注入-使用反射机制和动态代理技术 - 简单思想(咋个办呢 zgbn)
- php 反射 依赖注入
- 学习php反射(3)——一个依赖注入的例子
- 【转】理解 PHP 依赖注入 | Laravel IoC容器
- php反射学习之依赖注入示例
- php: CGI faseCGI PHP-FPM | laravel启动过程 | php依赖注入
- 理解PHP 依赖注入|Laravel IoC容器
- php中的反射,依赖注入与控制反转
- Laravel框架下容器Container 的依赖注入和反射应用
- 理解PHP 依赖注入|Laravel IoC容器
- PHP基于反射机制实现自动依赖注入的方法详解
- PHP反射机制实现自动依赖注入
- php中的依赖注入
- 8-spring源码3.2.18解读+spring技术内幕(IOC容器的依赖注入(反射+递归调用))
- 如何理解php的依赖注入
- php 依赖注入
- 反射、注解与依赖注入总结
- [李景山php] 依赖注入和设计模式