> 백엔드 개발 > PHP 튜토리얼 > PHP 게으른 개체를 사용하여 PSR 호환 종속성 주입 컨테이너 구축

PHP 게으른 개체를 사용하여 PSR 호환 종속성 주입 컨테이너 구축

DDD
풀어 주다: 2025-01-04 09:45:39
원래의
195명이 탐색했습니다.

Building a PSR-Compatible Dependency Injection Container with PHP  Lazy Objects

PHP 8.4에서 게으른 개체를 사용한 종속성 주입 탐색

최신 PHP 영역에서는 버전 8.4 출시로 획기적인 기능인 게으른 객체가 도입되었습니다. 이러한 개체를 사용하면 꼭 필요할 때까지 초기화를 연기하여 성능을 향상하고 리소스 사용량을 줄이는 새로운 방법을 사용할 수 있습니다. 이 기능은 지연 개체 RFC에 대한 지연 초기화에 설명된 대로 ReflectionClass API의 향상된 기능을 통해 언어에 깊이 통합되었습니다.

RFC 예시
Lazy Objects의 잠재력을 설명하려면 RFC에서 직접 다음 예제를 고려하십시오.

class MyClass
{
    public function __construct(private int $foo)
    {
        // Heavy initialization logic here.
    }

    // ...
}

$initializer = static function (MyClass $ghost): void {
    $ghost->__construct(123);
};

$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyGhost($initializer);

// At this point, $object is a lazy ghost object.
로그인 후 복사
로그인 후 복사

이 메커니즘을 통해 개발자는 초기화 프로세스를 세밀하게 제어하여 리소스에 액세스할 때만 로드되도록 할 수 있습니다.

이 RFC에서 영감을 받아 최적의 성능을 위해 Lazy Objects API를 활용하여 PSR-11 호환 종속성 주입 컨테이너를 구축하기 시작했습니다.

ContainerLazyObject의 기초

컨테이너의 핵심은 ContainerLazyObject 클래스에 있습니다. 이를 통해 종속성을 등록하고 느리게 초기화할 수 있습니다. 즉, 실제로 필요할 때만 인스턴스화됩니다. 이 작업을 수행하는 주요 방법은 다음과 같습니다.

public function set(string $id, object|string $concrete): void
{
    $reflector = new ReflectionClass($id);
    $initializer = $concrete;

    if (is_string($concrete)) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete($this);
        };
    }

    if (is_object($concrete) && !$concrete instanceof Closure) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete;
        };
    }

    $this->instances[$id] = $reflector->newLazyGhost($initializer);
}

로그인 후 복사
로그인 후 복사
로그인 후 복사

컨테이너에 서비스 등록

저희 컨테이너는 다양한 서비스 등록 방법을 지원하여 개발자에게 유연성을 제공합니다. 다음은 몇 가지 예입니다.

$container = new ContainerLazyObject();
$containerer->set(DatabaseService::class, fn() => new DatabaseService(new LoggerService()));
$container->set(LoggerService::class, fn() => new LoggerService());

// Alternative approach with class names
$container->set(DatabaseService::class, DatabaseService::class);
$containerr->set(LoggerService::class, LoggerService::class);

// Using already instantiated objects
$container->set(DatabaseService::class, new DatabaseService(new LoggerService()));
$container->set(LoggerService::class, new LoggerService());

로그인 후 복사

이러한 유연성으로 인해 ContainerLazyObject는 동적으로 종속성을 구축하거나 사전 구성된 객체를 재사용하는 등 다양한 시나리오에 적응할 수 있습니다.

컨테이너에서 서비스 검색
서비스가 컨테이너에 등록되면 필요할 때마다 검색할 수 있습니다. 컨테이너는 서비스가 지연 인스턴스화되도록 보장하므로 실제로 요청될 때까지 서비스가 생성되지 않습니다. 등록된 서비스를 검색하는 방법의 예는 다음과 같습니다.

// Retrieving the services from the container
$loggerService = $container->get(LoggerService::class);
$databaseService = $container->get(DatabaseService::class);

로그인 후 복사

ContainerLazyObject의 핵심 컨테이너의 핵심은 ContainerLazyObject 클래스에 있습니다. 이를 통해 종속성을 등록하고 느리게 초기화할 수 있습니다. 즉, 실제로 사용될 때만 생성됩니다. 이 작업을 수행하는 주요 방법은 다음과 같습니다.

public function set(string $id, object|string $concrete): void
{
    $reflector = new ReflectionClass($id);
    $initializer = $concrete;

    if (is_string($concrete)) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete($this);
        };
    }

    if (is_object($concrete) && !$concrete instanceof Closure) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete;
        };
    }

    $this->instances[$id] = $reflector->newLazyGhost($initializer);
}

로그인 후 복사
로그인 후 복사
로그인 후 복사

PSR-11 호환성

ContainerLazyObject의 또 다른 장점은 종속성 주입 컨테이너의 PHP 표준인 PSR-11과의 호환성입니다. 이는 사양에 따른 라이브러리 및 프레임워크와의 상호 운용성을 보장하여 가볍고 보편적인 솔루션이 됩니다.

다른 컨테이너와의 성능 비교

컨테이너의 성능을 측정하기 위해 통제된 환경에서 PhpBench를 사용하여 인기 있는 대안인 Pimple, Illuminate 및 PHP-DI와 비교했습니다. 결과는 고무적이었습니다.

class MyClass
{
    public function __construct(private int $foo)
    {
        // Heavy initialization logic here.
    }

    // ...
}

$initializer = static function (MyClass $ghost): void {
    $ghost->__construct(123);
};

$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyGhost($initializer);

// At this point, $object is a lazy ghost object.
로그인 후 복사
로그인 후 복사

우리 컨테이너는 간단한 종속성 해결 시나리오에서 Illuminate Container 및 PHP-DI와 같은 보다 강력한 대안보다 훨씬 빠른 뛰어난 성능을 보여주었습니다.

완전한 수업

public function set(string $id, object|string $concrete): void
{
    $reflector = new ReflectionClass($id);
    $initializer = $concrete;

    if (is_string($concrete)) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete($this);
        };
    }

    if (is_object($concrete) && !$concrete instanceof Closure) {
        $initializer = function(object $instance) use ($concrete): void {
            $this->instances[$instance::class] = $concrete;
        };
    }

    $this->instances[$id] = $reflector->newLazyGhost($initializer);
}

로그인 후 복사
로그인 후 복사
로그인 후 복사

결론

PHP 8.4와 Lazy Objects는 종속성 주입을 단순화하고 최적화할 수 있는 새로운 가능성을 열었습니다. 우리의 ContainerLazyObject는 가볍고 효율적이며 유연할 뿐만 아니라 PSR-11을 준수하여 다른 라이브러리 및 프레임워크와의 상호 운용성을 보장합니다.

이 접근 방식을 시도해보고 다음 프로젝트에서 종속성 관리를 어떻게 단순화할 수 있는지 알아보세요!

위 내용은 PHP 게으른 개체를 사용하여 PSR 호환 종속성 주입 컨테이너 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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