当前位置: 首页 > 后端技术 > PHP

Laravel源码阅读(前奏-反射实例化对象)

时间:2023-03-29 22:02:47 PHP

说明了Laravel核心容器的一部分是在依赖注入时使用反射来实现类的实例化。这是一个简化的例子。用于代码测试的类/***坦克标准:必须能够射击*/interfaceTank{publicfunctionfire();}/***59辆坦克,使用100毫米火炮*/classTank59implementsTank{private$gun=100;publicfunctionfire(){echo$this->gun.PHP_EOL;}}/***增强版59,可使用100mm炮或120mm炮,默认120mm炮*/classTank59PlusimplementsTank{private$gun;publicfunction__construct($gun=120){if($gun!=100&&$gun!=120){thrownewException('口径不合适');}$this->gun=$gun;}publicfunctionfire(){echo$this->gun.PHP_EOL;}}/***超级版本59,可以使用任何口径的枪支,必须提供枪支*/classTank59SuperimplementsTank{private$gun;公共函数__construct($gun){$this->gun=$gun;}publicfunctionfire(){echo$this->gun.PHP_EOL;}}/***坦克营,装备59和59加强版,必须提供59和59加强版*/classTankArmyimplementsTank{private$tank59;私人$tank59Plus;公共函数__construct(Tank59$tank59,Tankk59Plus$tank59Plus){$this->tank59=$tank59;$this->tank59Plus=$tank59Plus;}publicfunctionfire(){echo$this->tank59->fire();echo$this->tank59Plus->fire();}}Container/***Arsenal*/classFactory{/***创建实体对象*/publicstaticfunctionbuild($blueprint){//Reflect,获取类详细信息$reflector=newReflectionClass($blueprint);//不能创建的类,比如接口,抽象类if(!$reflector->isInstantiable()){thrownewException('提供的不是坦克图纸,不能制造');}//获取类的构造函数$constructor=$reflector->getConstructor();if(is_null($constructor)){//没有构造函数,直接newreturnnew$blueprint;}$参数=[];//获取构造函数依赖的参数$dependencies=$constructor->getParameters();foreach($dependenciesas$dependency){if(is_null($dependency->getClass())){//依赖参数不是对象//如果构造函数参数有默认值,获取默认值if($dependency->isDefaultValueAvailable()){$parameters[]=$dependency->getDefaultValue();}}else{//依赖参数是对象,递归创建$parameters[]=self::build($dependency->getClass()->name);}}if(!$parameters){//存在构造方法,构造方法有参数,但没有提供实际参数,无法创建thrownewException('坦克缺少必要的零件,无法制造');}else{//使用反射提供的方法创建对象,并传入参数return$reflector->newInstanceArgs($parameters);}}}TestTank$tank=Factory::build(Tank::class);echo$tank->fire();//output//PHP致命错误:未捕获异常:提供的不是坦克蓝图,不能buildTank59$tank=Factory::build(Tank59::class);echo$tank->fire();//output//100Tank59Plus$tank=Factory::build(Tank59Plus::class);echo$tank->fire();//输出//120Tank59Super$tank=Factory::build(Tank59Super::class);echo$tank->fire();//输出//致命错误:未捕获异常:坦克缺少必要的部件,无法建造TankArmy$tank=Factory::build(TankArmy::class);echo$tank->fire();//output//100//120

猜你喜欢