栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

PHP基于反射机制实现自动依赖注入的方法详解

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

PHP基于反射机制实现自动依赖注入的方法详解

本文实例讲述了PHP基于反射机制实现自动依赖注入的方法。分享给大家供大家参考,具体如下:

依赖注入又叫控制反转,使用过框架的人应该都不陌生。很多人一看名字就觉得是非常高大上的东西,就对它望而却步,今天抽空研究了下,解开他它的神秘面纱。废话不多说,直接上代码;


class Ioc {
  // 获得类的对象实例
  public static function getInstance($className) {
    $paramArr = self::getMethodParams($className);
    return (new ReflectionClass($className))->newInstanceArgs($paramArr);
  }
  
  public static function make($className, $methodName, $params = []) {
    // 获取类的实例
    $instance = self::getInstance($className);
    // 获取该方法所需要依赖注入的参数
    $paramArr = self::getMethodParams($className, $methodName);
    return $instance->{$methodName}(...array_merge($paramArr, $params));
  }
  
  protected static function getMethodParams($className, $methodsName = '__construct') {
    // 通过反射获得该类
    $class = new ReflectionClass($className);
    $paramArr = []; // 记录参数,和参数类型
    // 判断该类是否有构造函数
    if ($class->hasMethod($methodsName)) {
      // 获得构造函数
      $construct = $class->getMethod($methodsName);
      // 判断构造函数是否有参数
      $params = $construct->getParameters();
      if (count($params) > 0) {
 // 判断参数类型
 foreach ($params as $key => $param) {
   if ($paramClass = $param->getClass()) {
     // 获得参数类型名称
     $paramClassName = $paramClass->getName();
     // 获得参数类型
     $args = self::getMethodParams($paramClassName);
     $paramArr[] = (new ReflectionClass($paramClass->getName()))->newInstanceArgs($args);
   }
 }
      }
    }
    return $paramArr;
  }
}

上面的代码使用php的反射函数,创建了一个容器类,使用该类来实现其他类的依赖注入功能。上面的依赖注入分为两种,一种是构造函数的依赖注入,一种是方法的依赖注入。 我们使用下面三个类来做下测试。

class A {
  protected $cObj;
  
  public function __construct(C $c) {
    $this->cObj = $c;
  }
  public function aa() {
    echo 'this is A->test';
  }
  public function aac() {
    $this->cObj->cc();
  }
}
class B {
  protected $aObj;
  
  public function __construct(A $a) {
    $this->aObj = $a;
  }
  
  public function bb(C $c, $b) {
    $c->cc();
    echo "rn";
    echo 'params:' . $b;
  }
  
  public function bbb() {
    $this->aObj->aac();
  }
}
class C {
  public function cc() {
    echo 'this is C->cc';
  }
}

测试构造函数的依赖注入

// 使用Ioc来创建B类的实例,B的构造函数依赖A类,A的构造函数依赖C类。
$bObj = Ioc::getInstance('B');
$bObj->bbb(); // 输出:this is C->cc , 说明依赖注入成功。
// 打印$bObj
var_dump($bObj);
// 打印结果,可以看出B中有A实例,A中有C实例,说明依赖注入成功。
object(B)#3 (1) {
 ["aObj":protected]=>
 object(A)#7 (1) {
  ["cObj":protected]=>
  object(C)#10 (0) {
  }
 }
}

测试方法依赖注入

Ioc::make('B', 'bb', ['this is param b']);
// 输出结果,可以看出依赖注入成功。
this is C->cc
params:this is param b

从上面两个例子可以看出我们创建对象或者调用方法时,根本就不用知道该类或该方法依赖了那个类。使用反射机制可以轻松的为我们自动注入所需要的类。

总结

好了,看到上面的代码是不是觉得很简单,其实只要熟悉php的反射机制,依赖注入并不难实现,上面的代码为了方便理解,所以写的简单除暴,在实际的项目中肯定不会这么简单,比如:会对注入的类和参数进行配置,比如会缓存实例化过的类,下次需要该类的实例时,可以直接使用,而不用在重新初始化,等等。不过相信原理了解了,其他的可以随着项目的需求自己去完善。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/40052.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号