CakePHP 4.1에 도입 될 수있는 DI 컨테이너 "phpleague/container"를 사용해보십시오.

11268 단어 CakePHP4PHPCakePHP
이 문서는 CakePHP Advent Calendar 2019의 19 일째 항목입니다.

소개



요 전날 기다렸던 CakePHP4.0.0이 공식 출시되었습니다

그리고, 빨리 빠르지만 4.0계가 릴리스되었다고 하는 것은, 다음의 큰 업데이트는 4.1계의 릴리스라는 것이 됩니다. (정말 빨리 죄송합니다)

그런 것도 있어 조속히 4.1 로드맵 를 칠라 보고 보았습니다만 응용 의 란에 이하와 같은 기술이 있어, 왠지 재미있는 것 같은 변화가 일어날 것 같다고 느꼈습니다.
  • Experimental support for PSR11 compliant dependency injection container. Potential libraries that we could use are:
  • phpleague/container - h tps://이런 r.ぇphpぇ아구에. 이 m/3. x


  • 일본어로 번역하면 「PSR11 준거의 DI 컨테이너를 시험 도입할지도. phpleague/container 라고 하는 라이브러리에 가능성을 느끼고 있어.

    그래서이 기사에서는 Cake4.1에 도입 될 수있는 DI 컨테이너 라이브러리 인 phpleague/container을 시도하고 싶습니다.

    면책 조항


  • DI 또는 DI 컨테이너 자체는 설명하지 않습니다.
  • 인터넷이나 책에 훌륭한 기사나 문헌이 있으므로 그쪽을 참조해 주세요.


  • 설치



    composer로 바삭하게 설치할 수 있습니다. 그건 그렇고, 2019 년 12 월 현재 3.3.0이 설치됩니다.
    $ composer require league/container
    

    클라이언트 및 서비스 클래스 만들기



    우선은 클라이언트 클래스(객체가 주입되는 클래스)와 서비스 클래스(주입 대상이 되는 객체의 클래스)를 작성합니다. 흔한 Constructor Injection입니다.

    basic.php
    <?php declare(strict_types=1);
    
    namespace Basic;
    
    class Client
    {
        /**
         * @var Service
         */
        public $service;
    
        /**
         * Constructor Injection
         *
         * @param Service $service
         */
        public function __construct(Service $service)
        {
            $this->service = $service;
        }
    }
    
    class Service
    {
    }
    

    DI 컨테이너 만들기



    준비가 되었으므로 phpleague/container를 사용하여 DI 컨테이너를 만듭니다.

    basic.php
    // DI Container
    require 'vendor/autoload.php';
    
    use League\Container\Container;
    
    $container = new Container;
    
    $container->add(Service::class);
    $container->add('client_alias', Client::class)->addArgument(Service::class);
    
    $client1 = $container->get('client_alias');
    $client2 = $container->get('client_alias');
    
    var_dump($client1 instanceof Client); // true
    var_dump($client1->service instanceof Service); // true
    var_dump($client1 === $client2); //false
    
    add() 메서드를 사용하여 등록하고 get() 메서드를 사용하여 인스턴스를 가져옵니다. 별칭 이름 설정 등도 쉽게 할 수 있습니다.

    인터페이스 사용



    실제로 DI 컨테이너를 이용할 때는, 인터페이스를 이용해 구상 클래스를 은폐하는 것이 많다고 생각하므로, 그 패턴도 간단하게 써 보고 싶습니다.

    advance.php
    <?php declare(strict_types=1);
    
    namespace Advance;
    
    class Client
    {
        /**
         * @var ServiceInterface
         */
        public $service;
    
        /**
         * Constructor Injection
         *
         * @param ServiceInterface $service
         */
        public function __construct(ServiceInterface $service)
        {
            $this->service = $service;
        }
    }
    
    interface ServiceInterface
    {
    }
    
    class CakeService implements ServiceInterface
    {
    }
    
    class LaravelService implements ServiceInterface
    {
    }
    
    // DI Container
    require 'vendor/autoload.php';
    
    use League\Container\Container;
    
    $container = new Container;
    
    $container->add(ServiceInterface::class, CakeService::class);
    $container->add(Client::class)->addArgument(ServiceInterface::class);
    
    $client = $container->get(Client::class);
    
    var_dump($client instanceof Client); // true
    var_dump($client->service instanceof ServiceInterface); // true
    var_dump($client->service instanceof CakeService); // true
    var_dump($client->service instanceof LaravelService); // false
    

    인터페이스를 이용한 경우에서도 똑같이 빨리 DI 컨테이너를 만들 수 있습니다.

    요약



    몇 줄의 설명으로 간단하게 1 DI 컨테이너를 실현할 수 있었습니다. 이번에는 정말로 시도해 보았던 레벨이지만, 좀 더 깊은 해자를 하고 CakePHP에서 이 라이브러리가 어떻게 사용되는지 상상하는 것도 재미있을 것 같습니다. 2 덧붙여서 문서 사이트가 멋지고 텐션이 올랐습니다

    그래서 2020년도 CakePHP의 동향에서 눈을 뗄 수 없습니다!



    간단하다고 하면서 문서에 써 있는 채로 하고 있으면Autoload의 설정에 빠져, 저자에게 질문하는 등 하고 있었습니다. (즉석에서 대응해 주신 하나님이었습니다

    Issue를 세세하게 Watch하지 않기 때문에, 어쩌면 이미 논의되고 있을지도 모릅니다. 

    좋은 웹페이지 즐겨찾기