Slim Framework 매뉴얼 Routing (라우팅) #3 컨테이너

라우팅 (Routing)

Slim Framework의 라우터는 Fast Route 구성 요소 위에 구축되었으며, 매우 빠르고 안정적입니다. 이 구성 요소를 사용하여 모든 라우팅을 수행하는 동안 앱(app)의 코어는 완전히 분리되었으며 인터페이스는 다른 라우팅 라이브러리를 사용할 수 있는 기반을 마련했습니다.

컨테이너 해결방안 (Container Resolution)

라우트의 함수를 정의하는 데만 국한되지 않습니다. Slim에는 라우트 동작 기능을 정의하는 몇 가지 다른 방법이 있습니다.

기능 외에도 다음을 사용할 수 있습니다.

  • container_key:method
  • Class:method
  • Class implementing __invoke() method
  • container_key

이 기능은 Slim의 Callable Resolver Class에서 사용할 수 있습니다. 문자열 항목을 함수 호출로 변환합니다. 예:

$app->get('/', '\HomeController:home');

IDE 조회 시스템과 잘 작동하여 동일한 결과를 생성하는 PHP의 ‘::class’ 연산자를 사용할 수도 있습니다.

$app->get('/', \HomeController::class . ':home');

첫 번째 요소는 클래스 이름을 포함하고 두 번째 요소는 호출되는 메서드의 이름을 포함하는 배열을 전달할 수도 있습니다.

$app->get('/', [\HomeController::class, 'home']);

위의 코드에서는 ‘/’ 경로를 정의하고 Slim에게 ‘HomeController’ 클래스에서 ‘home()’ 메소드를 실행하도록 지시하고 있습니다.

Slim은 먼저 컨테이너에서 ‘HomeController’의 항목을 찾고, 발견되면 해당 인스턴스를 사용합니다. 그렇지 않으면 컨테이너를 첫 번째 인수로 사용하여 생성자를 호출합니다. 클래스의 인스턴스가 만들어지면 사용자가 정의한 모든 전략을 사용하여 지정된 메서드를 호출합니다.

컨테이너에 컨트롤러 등록 (Registering a controller with the container)

‘home’ 동작 방법으로 컨트롤러를 만듭니다. 생성자는 필요한 종속성을 수락해야 합니다. 예:

<?php
​
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Views\Twig;
​
class HomeController
{
    private $view;
​
    public function __construct(Twig $view)
    {
        $this->view = $view;
    }
    
    public function home(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
      // your code here
      // use $this->view to render the HTML
      // ...
      
      return $response;
    }
}

컨테이너에 종속성을 가진 컨트롤러를 인스턴스화하는 팩토리를 생성합니다.

use Psr\Container\ContainerInterface;
// ...
​
$container = $app->getContainer();
​
$container->set('HomeController', function (ContainerInterface $container) {
    // retrieve the 'view' from the container
    $view = $container->get('view');
    
    return new HomeController($view);
});

따라서 컨테이너를 의존성 주입에 활용할 수 있으므로 컨트롤러에 특정 종속성을 주입할 수 있습니다.

Slim이 컨트롤러를 인스턴스화할 수 있도록 허용 (Allow Slim to instantiate the controller)

또는 클래스에 컨테이너에 항목이 없으면 Slim은 컨테이너의 인스턴스를 생성자에게 전달합니다. 하나의 작업만 처리하는 호출 가능한 클래스 대신 많은 작업이 있는 컨트롤러를 구성할 수 있습니다.

<?php

use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class HomeController
{
  private $container;

  // constructor receives container instance
  public function __construct(ContainerInterface $container)
  {
      $this->container = $container;
  }

  public function home(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
  {
       // your code to access items in the container... $this->container->get('');
       
       return $response;
  }

  public function contact(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
  {
       // your code to access items in the container... $this->container->get('');
       
       return $response;
  }
}

이렇게 컨트롤러 메서드를 사용할 수 있습니다.

$app->get('/', \HomeController::class . ':home');
$app->get('/contact', \HomeController::class . ':contact');

호출할 수 없는 클래스 사용 (Using an invokable class)

라우트에서 호출 가능한 메서드를 지정할 필요는 없으며 다음과 같이 호출할 수 없는 클래스로 설정할 수 있습니다.

<?php
​
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
​
class HomeAction
{
   private $container;
​
   public function __construct(ContainerInterface $container)
   {
       $this->container = $container;
   }
​
   public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
   {
        // your code to access items in the container... $this->container->get('');
        
        return $response;
   }
}

이렇게 이 클래스를 이용하시면 됩니다.

$app->get('/', \HomeAction::class);

컨트롤러와 마찬가지로 클래스 이름을 컨테이너에 등록하면 팩토리를 생성하고 필요한 특정 종속성만 작업 클래스에 주입할 수 있습니다.