PHP Reflection API란
PHP Reflection API는, 클래스·메서드·프로퍼티·함수·파라미터 등의 메타 정보를 실행 시에 취득·검사할 수 있는 PHP의 내장 기능입니다. 클래스의 컨스트럭터가 무엇을 인수로 취하는지, 메서드에 어떤 어트리뷰트가 붙어 있는지 등을, 소스 코드를 직접 다시 쓰지 않고 조사할 수 있습니다. Laravel은Illuminate/Container/Container.php의 내부에서 Reflection API를 다용하고 있으며, DI 컨테이너의 자동 해결·PHP 어트리뷰트의 읽어들이기·메서드 인젝션 등을 실현하고 있습니다.
주요 클래스
ReflectionClass — 클래스 정보를 취득한다
ReflectionParameter — 컨스트럭터 인수를 검사한다
Laravel 컨테이너와 Reflection API
Laravel의 IoC 컨테이너는, Reflection API를 사용해 컨스트럭터 인젝션(의존성의 자동 해결)을 실현하고 있습니다.app()->make(SomeClass::class)나 의존성 주입이 작동하는 구조를 이해합시다.
컨테이너의 build() 메서드(간략판)
실제의 Container.php의 build() 메서드는 대략 다음과 같은 코드입니다.
Util::getParameterClassName()은 $parameter->getType()의 결과에서 타입명의 문자열을 꺼내는 유틸리티입니다. ReflectionParameter::getType()이 반환하는 ReflectionNamedType을 다루기 쉽게 래핑하고 있습니다.PHP 어트리뷰트의 읽어들이기
PHP 8.0 이후, Reflection API를 사용해 클래스·메서드·프로퍼티에 붙은 어트리뷰트를 취득할 수 있습니다. Laravel은 이 구조를 사용해 큐 어트리뷰트나 Eloquent 어트리뷰트를 처리하고 있습니다.어트리뷰트를 읽어들이는 기본 패턴
Laravel이 Queue 속성을 읽어들이는 구조(간략판)
메서드의 어트리뷰트를 읽어들인다
패키지 개발에서의 활용 예
클래스의 구현 인터페이스를 검사한다
패키지에서 클래스가 특정 인터페이스를 구현하고 있는지를 동적으로 확인할 수 있습니다.메타데이터 취득 — 어트리뷰트로 라우트를 자동 등록한다
어트리뷰트와 Reflection을 조합해 라우트를 자동 수집하는 패턴입니다.동적인 메서드 호출 — 메서드 인젝션
Laravel의call() 메서드는 Reflection을 사용해 인수를 자동 해결합니다. 같은 구조를 패키지에서 구현하는 예입니다.
프로퍼티의 기본값을 수집한다
설정 클래스의 기본값을 Reflection으로 취득하는 패턴입니다.퍼포먼스에의 배려
Reflection API는 클래스 정보를 매번 파스하기 때문에 비용이 듭니다. 프로덕션 코드에서는 결과를 캐시하는 것이 베스트 프랙티스입니다.다음 단계
PHP 어트리뷰트
ReflectionClass::getAttributes()를 사용해 읽어들이는 PHP 어트리뷰트의 상세를 배웁니다.
패키지 개발
Reflection API를 활용한 Laravel 패키지의 개발 방법을 배웁니다.