> 백엔드 개발 > PHP 튜토리얼 > PHP가 리플렉션 메커니즘을 기반으로 자동 종속성 주입을 구현하는 방법에 대한 자세한 설명

PHP가 리플렉션 메커니즘을 기반으로 자동 종속성 주입을 구현하는 방법에 대한 자세한 설명

*文
풀어 주다: 2023-03-18 08:36:01
원래의
1961명이 탐색했습니다.

이 글에서는 주로 리플렉션 메커니즘을 기반으로 PHP에서 자동 종속성 주입을 수행하는 방법을 소개합니다. PHP에서 자동 종속성 주입을 구현하기 위해 리플렉션을 사용하는 단계, 원리 및 관련 작동 기술을 예제 형식으로 분석합니다.

다시 의존성 주입을 제어 역전이라고 하는데, 프레임워크를 사용해 본 사람이라면 누구나 익숙할 것입니다. 많은 사람들이 이름을 보고 매우 고급스러운 제품이라고 생각하고 겁을 먹습니다. 오늘은 시간을 내어 조사를 하고 그 미스터리를 풀어봤습니다. 더 이상 고민하지 않고 바로 코드로 넘어가겠습니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

/**

*

* 工具类,使用该类来实现自动依赖注入。

*

*/

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;

  }

}

로그인 후 복사


위 코드는 PHP의 리플렉션 함수를 사용하여 컨테이너 클래스를 만들고 이 클래스를 사용하여 다른 클래스의 종속성 주입 기능을 구현합니다. 위의 의존성 주입은 생성자의 의존성 주입과 메소드의 의존성 주입 두 가지로 나누어진다. 테스트를 위해 다음 세 가지 클래스를 사용합니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

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';

  }

}

로그인 후 복사


생성자의 테스트 종속성 주입

1

2

3

4

5

6

7

8

9

10

11

12

13

14

// 使用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) {

  }

 }

}

로그인 후 복사

테스트 메서드 종속성 주입

1

2

3

4

Ioc::make('B', 'bb', ['this is param b']);

// 输出结果,可以看出依赖注入成功。

this is C->cc

params:this is param b

로그인 후 복사


위의 두 예에서 우리는 객체를 생성하거나 메소드를 호출할 때 클래스 또는 이 메서드는 해당 클래스에 따라 달라집니다. 리플렉션 메커니즘을 사용하면 필요한 클래스를 쉽게 자동으로 주입할 수 있습니다.

요약

알겠습니다. 위 코드가 매우 간단하다고 생각하시나요? 사실, PHP의 리플렉션 메커니즘만 알면 종속성 주입은 구현하기 어렵지 않습니다. 위 코드는 이해를 돕기 위해 간단하게 작성되었습니다. 실제로는 프로젝트에서 그렇게 간단하지 않을 것입니다. 예를 들어, 인스턴스화된 클래스는 다음에 클래스 인스턴스가 필요할 때 캐시됩니다. 재초기화 등의 작업 없이 직접 사용하세요. 하지만 일단 원칙을 이해하면 프로젝트의 필요에 따라 나머지 부분을 개선할 수 있다고 믿습니다.


관련 읽기:

php 반사 사용 예제

PHP 반사 사용 예제 코드

동적 프록시

위 내용은 PHP가 리플렉션 메커니즘을 기반으로 자동 종속성 주입을 구현하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿