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

PHP反射机制实现自动依赖注入

时间:2023-03-29 17:39:13 PHP

依赖注入也叫控制反转,用过框架的人应该不陌生。很多人看到名字就觉得它是一个很高大上的东西,所以对它心生畏惧,今天就来揭开它的神秘面纱。废话不多说,直接上代码;/****工具类,使用该类实现自动依赖注入。**/classIoc{//获取类的对象实例publicstaticfunctiongetInstance($className){$paramArr=self::getMethodParams($className);返回(newReflectionClass($className))->newInstanceArgs($paramArr);}/***执行类方法*@param[类型]$className[类名]*@param[类型]$methodName[方法名]*@param[类型]$params[额外参数]*@return[类型][说明]*/publicstaticfunctionmake($className,$methodName,$params=[]){//获取类的实例$instance=self::getInstance($className);//获取需要依赖注入的方法参数实例$paramArr=self::getMethodParams($className,$methodName);返回$instance->{$methodName}(...array_merge($paramArr,$params));}/***获取类对于方法参数,只获取有类型的参数*@param[type]$className[description]*@param[type]$methodsName[description]*@return[type][description]*/protected静态函数getMethodParams($className,$methodsName='__construct'){//通过反射获取类$class=newReflectionClass($className);$paramArr=[];//记录参数,以及参数类型//判断类是否有构造函数if($class->hasMethod($methodsName)){//获取构造函数$construct=$class->getMethod($methodsName);//判断构造函数是否有参数$params=$construct->getParameters();if(count($params)>0){//判断参数类型foreach($paramsas$key=>$param){if($paramClass=$param->getClass()){//获取参数类型名称$paramClassName=$paramClass->getName();//获取参数类型$args=self::getMethodParams($paramClassName);$paramArr[]=(newReflectionClass($paramClass->getName()))->newInstanceArgs($args);}}}}返回$paramArr;}}上述代码利用php的反射功能创建了一个容器类,用于实现其他类的依赖注入功能。上面的依赖注入分为两种,一种是构造函数的依赖注入,另一种是方法依赖注入。我们使用下面三个类来做接下来的测试。A类{受保护的$cObj;/***用于测试多级依赖注入B依赖A,A依赖C*@paramC$c[说明]*/publicfunction__construct(C$c){$this->cObj=$c;}publicfunctionaa(){echo'这是A->test';}publicfunctionaac(){$this->cObj->cc();}}B类{受保护的$aObj;/***测试构造函数依赖注入*@paramA$a[使用引用注入A]*/publicfunction__construct(A$a){$this->aObj=$a;}/***[测试方法调用依赖注入]*@paramC$c[依赖注入C]*@paramstring$b[这是你手动填写的参数]*@return[类型][描述]*/公共函数bb(C$c,$b){$c->cc();回声“\r\n”;回声“参数:”。$b;}/***验证依赖注入是否成功*??@return[type][description]*/publicfunctionbbb(){$this->aObj->aac();}}classC{publicfunctioncc(){echo'这是C->cc';}}测试构造函数依赖注入://使用Ioc创建B类的An实例,B的构造函数依赖类A,A的构造函数构造函数依赖类C$bObj=Ioc::getInstance('B');$bObj->bbb();//输出:这是C->cc,说明依赖注入成功。//Print$bObjvar_dump($bObj);//打印结果,可以看出B中有A的实例,A中有C的实例,说明依赖注入成功。对象(B)#3(1){["aObj":protected]=>对象(A)#7(1){["cObj":protected]=>对象(C)#10(0){}}}测试方法依赖注入:ioc::make('B','bb',['thisisparamb']);//输出结果,可见依赖注入成功。thisisC->ccparams:thisisparamb 从上面两个例子可以看出,我们在创建对象或者调用方法的时候,不需要知道类或者方法依赖的类在。使用反射机制可以方便的自动为我们注入需要的类。