Method to implement automatic dependency injection based on reflection mechanism in PHP

墨辰丷
Release: 2023-03-26 07:40:02
Original
2670 people have browsed it

This article mainly introduces the method of automatic dependency injection in PHP based on the reflection mechanism. It analyzes the steps, principles and related operating techniques of using reflection to realize automatic dependency injection in PHP in the form of examples. Friends in need can refer to it

The example in this article describes how PHP implements automatic dependency injection based on the reflection mechanism. I share it with you for your reference. The details are as follows:

Dependency injection is also called inversion of control. Anyone who has used the framework should be familiar with it. Many people think it is something very high-end when they see the name, and are daunted by it. Today I took the time to do some research and unravel its mystery. Without further ado, let’s go straight to the code;

/**
*
* 工具类,使用该类来实现自动依赖注入。
*
*/
class Ioc {
  // 获得类的对象实例
  public static function getInstance($className) {
    $paramArr = self::getMethodParams($className);
    return (new ReflectionClass($className))->newInstanceArgs($paramArr);
  }
  /**
   * 执行类的方法
   * @param [type] $className [类名]
   * @param [type] $methodName [方法名称]
   * @param [type] $params   [额外的参数]
   * @return [type]       [description]
   */
  public static function make($className, $methodName, $params = []) {
    // 获取类的实例
    $instance = self::getInstance($className);
    // 获取该方法所需要依赖注入的参数
    $paramArr = self::getMethodParams($className, $methodName);
    return $instance->{$methodName}(...array_merge($paramArr, $params));
  }
  /**
   * 获得类的方法参数,只获得有类型的参数
   * @param [type] $className  [description]
   * @param [type] $methodsName [description]
   * @return [type]       [description]
   */
  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;
  }
}
Copy after login

The above code uses PHP’s reflection function to create a container class and use this class to implement other classes Dependency injection function. The above dependency injection is divided into two types, one is dependency injection of constructor, and the other is dependency injection of method. We use the following three classes for testing.

class A {
  protected $cObj;
  /**
   * 用于测试多级依赖注入 B依赖A,A依赖C
   * @param C $c [description]
   */
  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;
  /**
   * 测试构造函数依赖注入
   * @param A $a [使用引来注入A]
   */
  public function __construct(A $a) {
    $this->aObj = $a;
  }
  /**
   * [测试方法调用依赖注入]
   * @param C   $c [依赖注入C]
   * @param string $b [这个是自己手动填写的参数]
   * @return [type]  [description]
   */
  public function bb(C $c, $b) {
    $c->cc();
    echo "\r\n";
    echo 'params:' . $b;
  }
  /**
   * 验证依赖注入是否成功
   * @return [type] [description]
   */
  public function bbb() {
    $this->aObj->aac();
  }
}
class C {
  public function cc() {
    echo 'this is C->cc';
  }
}
Copy after login

Test dependency injection of constructor

// 使用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) {
  }
 }
}
Copy after login

Test method dependency injection

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

It can be seen from the above two examples that when we create an object or call a method, we don’t need to know the The class or this method depends on that class. Using the reflection mechanism can easily automatically inject the required classes for us.

Related recommendations:

Detailed explanation of PHP reflection mechanism

Brief introduction to detailed explanation of examples of PHP reflection mechanism

What is the principle of php reflection mechanism? Detailed explanation of the function of the reflection mechanism

##

The above is the detailed content of Method to implement automatic dependency injection based on reflection mechanism in PHP. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!