PHP 클래스 리플렉션 구현의 종속성 주입 프로세스에 대한 자세한 설명

小云云
풀어 주다: 2023-03-19 22:22:01
원래의
2386명이 탐색했습니다.

PHP에는 클래스, 인터페이스, 함수, 메소드 및 확장을 리버스 엔지니어링할 수 있는 기능을 제공하는 완전한 리플렉션 API가 있습니다. 클래스 리플렉션에서 제공하는 기능을 통해 클래스가 정의되는 방법, 클래스에 포함된 속성, 클래스에 포함된 메서드, 메서드에 포함된 매개변수, 클래스 파일에 대한 경로 및 기타 매우 중요한 정보를 알 수 있습니다. 많은 PHP 프레임워크가 종속성 주입을 구현하여 클래스 간의 종속성을 자동으로 해결할 수 있는 것도 클래스 반영 덕분에 일상적인 개발에 큰 편의를 제공합니다.

이 글에서는 주로 클래스 리플렉션을 사용하여 종속성 주입(Dependency Injection)을 구현하는 방법을 설명합니다. PHP 리플렉션의 모든 API를 하나씩 설명하지는 않습니다. 이 글에서는 주로 공식 문서를 참조하시기 바랍니다. PHP 수업을 통해 의존성 주입 프로세스를 구현하고 관련 지식을 공유할 수 있습니다. 이에 관심이 있는 친구는 편집자를 따라 학습할 수 있기를 바랍니다.

더 나은 이해를 위해 클래스 리플렉션과 종속성 주입 구현 방법을 예제를 통해 살펴보겠습니다.

다음 클래스는 좌표계의 한 점을 나타내며 가로좌표 x와 세로좌표 y라는 두 가지 속성을 갖습니다.


/**
 * Class Point
 */
class Point
{
  public $x;
  public $y;

  /**
   * Point constructor.
   * @param int $x horizontal value of point's coordinate
   * @param int $y vertical value of point's coordinate
   */
  public function __construct($x = 0, $y = 0)
  {
    $this->x = $x;
    $this->y = $y;
  }
}
로그인 후 복사

다음 클래스는 원을 나타냅니다. 생성자에는 Point 클래스의 매개변수가 있습니다. 즉, Circle 클래스는 Point 클래스에 종속됩니다.


class Circle
{
  /**
   * @var int
   */
  public $radius;//半径

  /**
   * @var Point
   */
  public $center;//圆心点

  const PI = 3.14;

  public function __construct(Point $point, $radius = 1)
  {
    $this->center = $point;
    $this->radius = $radius;
  }
  
  //打印圆点的坐标
  public function printCenter()
  {
    printf('center coordinate is (%d, %d)', $this->center->x, $this->center->y);
  }

  //计算圆形的面积
  public function area()
  {
    return 3.14 * pow($this->radius, 2);
  }
}
로그인 후 복사

ReflectionClass

다음으로 리플렉션을 통해 Circle 클래스를 리버스 엔지니어링합니다.

Circle 클래스의 이름을 ReflectionClass에 전달하여 ReflectionClass 클래스의 개체를 인스턴스화합니다.


$reflectionClass = new reflectionClass(Circle::class);
//返回值如下
object(ReflectionClass)#1 (1) {
 ["name"]=>
 string(6) "Circle"
}
로그인 후 복사

클래스의 상수를 반영


$reflectionClass->getConstants();
로그인 후 복사

상수 이름과 값으로 구성된 연관 배열을 반환


array(1) {
 ["PI"]=>
 float(3.14)
}
로그인 후 복사

리플렉션을 통해 속성 가져오기


rreee

하나를 반환 ReflectionProperty 객체로 구성된 배열


$reflectionClass->getProperties();
로그인 후 복사

클래스에 정의된 메서드를 반영


array(2) {
 [0]=>
 object(ReflectionProperty)#2 (2) {
  ["name"]=>
  string(6) "radius"
  ["class"]=>
  string(6) "Circle"
 }
 [1]=>
 object(ReflectionProperty)#3 (2) {
  ["name"]=>
  string(6) "center"
  ["class"]=>
  string(6) "Circle"
 }
}
로그인 후 복사

ReflectionMethod 객체로 구성된 배열을 반환


$reflectionClass->getMethods();
로그인 후 복사

클래스를 별도로 얻을 수도 있습니다. getConstructor() 생성자의 반환 값은 ReflectionMethod 객체입니다.


array(3) {
 [0]=>
 object(ReflectionMethod)#2 (2) {
  ["name"]=>
  string(11) "__construct"
  ["class"]=>
  string(6) "Circle"
 }
 [1]=>
 object(ReflectionMethod)#3 (2) {
  ["name"]=>
  string(11) "printCenter"
  ["class"]=>
  string(6) "Circle"
 }
 [2]=>
 object(ReflectionMethod)#4 (2) {
  ["name"]=>
  string(4) "area"
  ["class"]=>
  string(6) "Circle"
 }
}
로그인 후 복사

메서드의 매개변수를 반영합니다


$constructor = $reflectionClass->getConstructor();
로그인 후 복사

반환값은 ReflectionParameter 개체로 구성된 배열입니다.


$parameters = $constructor->getParameters();
로그인 후 복사

종속성 주입

다음으로 make라는 함수를 작성하고, 클래스 이름을 make 함수에 전달하고 클래스의 객체를 반환합니다. make에서는 클래스의 종속성을 주입하는 데 도움이 됩니다. , 즉 이 예에서는 Circle 클래스의 생성자에 Point 개체를 삽입하는 데 도움이 됩니다.


array(2) {
 [0]=>
 object(ReflectionParameter)#3 (1) {
  ["name"]=>
  string(5) "point"
 }
 [1]=>
 object(ReflectionParameter)#4 (1) {
  ["name"]=>
  string(6) "radius"
 }
}
로그인 후 복사

make 메소드를 정의한 후 이를 사용하여 Circle 클래스의 객체를 인스턴스화합니다:


//构建类的对象
function make($className)
{
  $reflectionClass = new ReflectionClass($className);
  $constructor = $reflectionClass->getConstructor();
  $parameters = $constructor->getParameters();
  $dependencies = getDependencies($parameters);
  
  return $reflectionClass->newInstanceArgs($dependencies);
}

//依赖解析
function getDependencies($parameters)
{
  $dependencies = [];
  foreach($parameters as $parameter) {
    $dependency = $parameter->getClass();
    if (is_null($dependency)) {
      if($parameter->isDefaultValueAvailable()) {
        $dependencies[] = $parameter->getDefaultValue();
      } else {
        //不是可选参数的为了简单直接赋值为字符串0
        //针对构造方法的必须参数这个情况
        //laravel是通过service provider注册closure到IocContainer,
        //在closure里可以通过return new Class($param1, $param2)来返回类的实例
        //然后在make时回调这个closure即可解析出对象
        //具体细节我会在另一篇文章里面描述
        $dependencies[] = '0';
      }
    } else {
      //递归解析出依赖类的对象
      $dependencies[] = make($parameter->getClass()->name);
    }
  }

  return $dependencies;
}
로그인 후 복사

관련 권장 사항:

인스턴스 분석 Laravel의 종속성 주입

PHP는 다음을 기반으로 합니다. 반사 메커니즘 자동 종속성 주입 구현 방법에 대한 자세한 설명

PHP 종속성 주입 분석 방법

위 내용은 PHP 클래스 리플렉션 구현의 종속성 주입 프로세스에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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