2017-11-09 3 views
16

Laravel의 반사 효과는 실제로 어떻게 작용합니까?Laravel의 리플렉션은 어떻게 작동합니까?

Laravel이 컨트롤러의 생성자 또는 리플렉션을 사용하여 종속성 및 하위 종속성을 해결 한 다음이를 다시 제공하는 방법을 디버깅하려고했습니다.

그러나 나는 그것을 열심히 찾았고,보고, 심지어는 50 %를 이해하는 것이 매우 복잡합니다. 클래스에서 클래스로 점프, 나는 그것을 정말로 볼 수 없다. 낮은 이해력으로 디버깅하여 몇 번 시도했습니다.

나는 이것과 반사에 깊은 인상을 받았으며 Laravel이 사용하는 방식으로 내 마음이 타박상을 입습니다. 단지 아름답습니다. 그리고 전 과정, 일반적으로 단계별로 완전히 이해하고 싶습니다. $x = new TestClass(new TestClass2());

나는 사람들이 생각 : 마지막으로 가지고 할 수있는 경로를 타격에서 시작

,의는, $x가 메소드 인수에서이고를 통해 구성되어야한다 TestClass2의 또 다른 의존성이있는 TestClass입니다 dd($x)을 가정 해 봅시다 아름다운 기계공 및 건축술 및 이것을 이해하는 것은 나가 아주 나쁘게 원한다 무언가이다.

다시, 제 질문은 : Laravel의 반영이 실제로 어떻게 작동합니까?


dd들 ... 이제 dd없이 가정 해 봅시다 아닙니다. 이전에 말했듯이 - class method에서이 객체를 인스턴스화했을 때. 투기에 관한 것이 아니라 method injection부터 reflection까지입니다.

dd은 예일뿐입니다. die(var_dump()); 일 수도 있고 작동 할 수도 있습니다.

+0

여기에 매우 광범위한 질문을하고 있습니다.이 질문은 * 어떻게 작동합니까? * 스타일 질문에 가장 적합한 포럼이 아닙니다. 'dd' 자체는 리플렉션을 사용하여 객체에 대한 개인 정보를 출력합니다. 의존성 주입 레이어는이를 사용하여 대상 클래스의 종속성을 재귀 적으로 검사합니다. 특히 Laravel과 관련된 것은 없습니다. 변수 또는 DI를 덤프하는 대부분의 패키지는 비슷한 작업을 수행합니다. – iainn

+0

@iainn이 (가) 내 질문에 편집 됨 –

+0

Laravel은 (는) 반사에만 관한 것이 아닙니다. 후드 아래에서 진행되는 많은 일이 있습니다. 다음 기사를 읽어보십시오. http://alanstorm.com/category/laravel/#container – Hamoud

답변

27

Laravel은 PHP의 reflection API을 여러 구성 요소에 사용합니다. 이 중 제어 실패 (IoC) dependency injection container컨트롤러 method injection은 개발자에게 가장 잘 보입니다.

function build($className) 
{ 
    $reflector = new ReflectionClass($className); 
    $constructor = $reflector->getConstructor(); 

    foreach ($constructor->getParameters() as $dependency) { 
     $instances[] = build($dependency->getClass()->name); 
    } 

    return $reflector->newInstanceArgs($instances); 
} 

우리가 볼 수 있듯이, 개념 : 더 명확하게하려면

여기 루틴 Laravel의 IoC container class 생성자 주입을 통해 개체의 종속성을 구축하는 데 사용의 극적으로 단순화 된 버전의 반사를 사용하는 방법을 보여줍니다 이해하기 너무 어렵지 않다. 컨테이너는 PHP의 ReflectionClass을 사용하여 객체의 생성자에서 클래스의 이름을 찾은 다음 반복적으로 각 이름을 반복하여 종속성 트리에서 각 객체의 인스턴스를 만듭니다. 이러한 인스턴스를 사용하면 build()이 마침내 원래 클래스를 인스턴스화하고 종속성을 인수로 생성자에 전달합니다.

컨트롤러 메소드 주입

메소드 파라미터로서 선언 종속성의 인스턴스를 해결하기 위해 전술 한 바와 같은 컨테이너 기능을 사용하지만, 라우팅 파라미터에서 별도 클래스 종속성에 필요한 여분의 로직 비트있다 :

function dispatch(Route $route, Controller $controller, $methodName) 
{ 
    $routeParameters = $route->parametersWithoutNulls(); 
    $method = new ReflectionMethod($controller, $methodName); 

    foreach ($method->getParameters() as $index => $parameter) { 
     $class = $parameter->getClass(); 

     if ($class !== null) { 
      $instance = build($class->name); 
      array_splice($routeParameters, $index, 0, [ $instance ]); 
     } 
    } 

    $controller->callAction($methodName, $routeParameters); 
} 

는 또 ,이 적응은 반사 반향을 강조하기 위해 슬림화되고 이전에 표시된 build() 함수에 의존합니다.ControllerDispatcher 클래스는 PHP ReflectionMethod의 메서드를 사용하여 컨트롤러 메서드가 예상하는 매개 변수를 결정한 다음이를 통해 루프를 통해 컨테이너에서 해결할 수있는 종속성을 나타내는 매개 변수를 찾습니다. 그런 다음 발견 된 각 종속성을 라우트에 대해 정의 된 제어기 메소드로 다시 전달하는 라우트 매개 변수의 배열로 다시 연결합니다. 자세한 내용은 RouteDependencyResolverTrait을 참조하십시오.

응용 프로그램 부트 스트랩 프로세스를 무시하면이 종속성 주입 계단식은 일반적으로 Laravel이 요청을 경로에 매핑하고 요청을 전달할 컨트롤러를 결정할 때 요청에 대해 시작됩니다. Laravel은 컨테이너에서 컨트롤러의 인스턴스를 먼저 확인합니다.이 인스턴스는 생성자가 주입 한 종속성을 만듭니다. 그런 다음 Laravel은 적절한 컨트롤러 메서드를 찾고 필요에 따라 인수에 대한 더 이상의 종속성을 확인합니다.

여기에 표시된 것처럼 Laravel은 리플렉션을 사용하여 이러한 도구를 구현하는 비교적 간단한 기술을 사용합니다. 그러나이 답변에 표시된 예와 달리 프레임 워크는 오늘날과 같이 견고하고 유연 해 지도록 많은 추가 코드를 추가합니다.

관련 문제