>php教程 >PHP开发 >PHP 종속성 주입 컨테이너 시리즈 이해하기 (3) Symfony

PHP 종속성 주입 컨테이너 시리즈 이해하기 (3) Symfony

黄舟
黄舟원래의
2016-12-28 10:27:161651검색

지금까지 몇 가지 기본 개념에 대해 이야기했습니다. 처음 두 기사의 예는 종속성 주입 구현을 이해하는 데 매우 도움이 됩니다. 이제 Symfony 2 서비스 컨테이너 구현에 대해 자세히 살펴보겠습니다.
Symfony의 종속성 주입 컨테이너는 sfServiceContainer라는 클래스에 의해 관리됩니다.

Symfony 컨테이너는 독립적인 구성 요소로 존재할 수 있습니다. Symfony의 공식 Subversion 저장소는 http://svn .symfony-에서 다운로드할 수 있습니다. project.com/comComponents/dependent_injection/trunk/
. 이 구성 요소는 아직 지속적인 반복 개발 중이므로 언제든지 업데이트될 수 있다는 점에 주목할 필요가 있습니다(2009년에 언급되었으나 지금은 중단된 것 같습니다).

심포니의 디자인 철학에 따르면 모든 서비스는 컨테이너로 관리되는 객체가 될 수 있습니다. 이전 글에서 소개한 Zend_Mail 예제에는 mailer와 mail_transport라는 두 개의 객체가 있습니다

class Container
{
  static protected $shared = array();
  protected $parameters = array();
  public function __construct(array $parameters = array())
  {
    $this->parameters = $parameters;
  }
  public function getMailTransport()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => $this->parameters['mailer.username'],
      'password' => $this->parameters['mailer.password'],
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }
  public function getMailer()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }
    $class = $this->parameters['mailer.class'];
    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());
    return self::$shared['mailer'] = $mailer;
  }
}

Container 클래스가 Symfony의 sfServiceContainer 클래스를 상속받는다면 코드를 좀 더 간단하게 만들 수 있습니다

class Container extends sfServiceContainer
{
  static protected $shared = array();
  protected function getMailTransportService()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => $this['mailer.username'],
      'password' => $this['mailer.password'],
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }
  protected function getMailerService()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }
    $class = $this['mailer.class'];
    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransportService());
    return self::$shared['mailer'] = $mailer;
  }
}

관찰: 생성자 및 매개변수 구성 관리 코드가 생략되었습니다.
그러나 그것이 전부는 아닙니다. sfServiceContainer는 인터페이스를 사용할 때 주의해야 할 몇 가지 사항입니다.
1. 서비스. 일반적으로 메소드 이름은 get으로 시작하고 Service로 끝나는 데 동의합니다. 각 서비스에는 고유한 로고가 있습니다. 로고는 일반적으로 접두사와 접미사가 없고 밑줄로 구분된 메서드 이름입니다. getMailTransportService() 메소드가 정의된 경우 서비스 이름은 mail_transport
2. 메소드는 보호 유형이므로 서비스를 얻기 위해 메소드를 직접 호출할 수 없습니다. 컨테이너를 사용하여 서비스를 얻는 방법은 나중에 소개하겠습니다.
3. 전달된 매개변수를 얻기 위해 컨테이너에 배열로 액세스할 수 있습니다. 예: $this['mailer.class']
서비스 표시는 고유해야 하며 문자, 숫자, '_' 및 '.'로만 구성될 수 있습니다. '.'는 네임스페이스(예: mail.mailer 및 mail.transport)로 사용될 수 있습니다.

이제 이 새로운 컨테이너를 어떻게 사용하는지 살펴보겠습니다

require_once 'PATH/TO/sf/lib/sfServiceContainerAutoloader.php';
sfServiceContainerAutoloader::register();
$sc = new Container(array(
  'mailer.username' => 'foo',
  'mailer.password' => 'bar',
  'mailer.class'    => 'Zend_Mail',
));
$mailer = $sc->mailer;

Container 클래스는 sfServiceContainer를 상속받기 때문에 인터페이스가 매우 깔끔해집니다.

통합 인터페이스를 통해 서비스에 액세스

if ($sc->hasService('mailer'))
{
  $mailer = $sc->getService('mailer');
}
$sc->setService('mailer', $mailer);

더 간단한 방법은 속성을 통해 서비스에 액세스하는 것입니다

if (isset($sc->mailer))
{
  $mailer = $sc->mailer;
}
$sc->mailer = $mailer;
매개변수는 통합 인터페이스를 통해 액세스합니다. 인터페이스
if (!$sc->hasParameter('mailer_class'))
{
  $sc->setParameter('mailer_class', 'Zend_Mail');
}
echo $sc->getParameter('mailer_class');
// Override all parameters of the container
$sc->setParameters($parameters);
// Adds parameters
$sc->addParameters($parameters);

매개변수는 배열처럼 컨테이너를 통해서도 액세스할 수 있습니다.

if (!isset($sc['mailer.class']))
{
  $sc['mailer.class'] = 'Zend_Mail';
}
$mailerClass = $sc['mailer.class'];

컨테이너는 iterator, 모든 서비스 순회

foreach ($sc as $id => $service)
{
  echo sprintf("Service %s is an instance of %s.\n", $id, get_class($service));
}

관리할 서비스가 많지 않은 경우 기본적인 작업도 많이 하고 코드도 많이 복사해야 하지만, sfServiceContainer를 사용하는 것이 매우 유용하다는 것을 인정합니다.
관리해야 할 서비스가 점점 더 많아진다면, 서비스를 더 잘 설명할 수 있는 방법이 있어야 합니다.
이것이 대부분의 경우 sfServiceContainer 클래스를 직접 사용하지 않는 이유입니다. 그럼에도 불구하고 Symfony 종속성 주입 컨테이너의 중요한 초석이기 때문에 그것에 대해 이야기하는 데 시간을 할애할 필요가 있습니다.

위 내용은 PHP 의존성 주입 컨테이너 시리즈 이해 내용입니다. (3) Symfony 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.