Heim > php教程 > PHP开发 > Hauptteil

Verständnis der PHP Dependency Injection Container Series (3) Symfony

黄舟
Freigeben: 2016-12-28 10:27:16
Original
1599 Leute haben es durchsucht

Bisher haben wir über einige grundlegende Konzepte gesprochen. Die Beispiele in den ersten beiden Artikeln sind für uns sehr hilfreich, um die Implementierung der Abhängigkeitsinjektion zu verstehen. Jetzt werden wir uns eingehend mit der Implementierung des Symfony 2-Dienstcontainers befassen.
Der Abhängigkeitsinjektionscontainer in Symfony wird von einer Klasse namens sfServiceContainer verwaltet.

Der Symfony-Container kann als unabhängige Komponente existieren. Das offizielle Subversion-Repository von Symfony kann heruntergeladen werden: http://svn .symfony-. project.com/components/dependency_injection/trunk/
. Es ist erwähnenswert, dass sich diese Komponente immer noch in einer kontinuierlichen iterativen Entwicklung befindet, sodass sie jederzeit aktualisiert werden kann (so hieß es 2009, aber jetzt scheint es damit aufgehört zu haben).

Gemäß der Designphilosophie von Symfony kann jeder Dienst ein Objekt sein, das von einem Container verwaltet wird. In dem im vorherigen Artikel vorgestellten Zend_Mail-Beispiel gibt es zwei Objekte: mailer und 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;
  }
}
Nach dem Login kopieren

Wenn die Container-Klasse die sfServiceContainer-Klasse von Symfony erbt, kann der Code etwas einfacher gestaltet werden

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;
  }
}
Nach dem Login kopieren

Durch Beobachtung: Der Konstruktor- und Parameterkonfigurationsverwaltungscode wird weggelassen.
Aber das ist noch nicht alles. sfServiceContainer kann uns eine leistungsstarke und übersichtliche Schnittstelle bieten. Folgende Punkte sind bei der Verwendung der Schnittstelle zu beachten:
Der Name der Methode zum Abrufen des Dienstes muss angehängt werden Service. Normalerweise sind wir uns einig, dass der Name der Methode mit get beginnt und mit Service endet. Jeder Dienst verfügt über ein eindeutiges Logo. Das Logo ist normalerweise der Methodenname ohne Präfix und Suffix, getrennt durch Unterstriche. Wenn die Methode getMailTransportService() definiert ist, lautet der Dienstname mail_transport
2. Die Methode ist vom geschützten Typ, was bedeutet, dass Sie die Methode nicht direkt aufrufen können, um den Dienst zu erhalten. Wir werden später vorstellen, wie Container zum Abrufen von Diensten verwendet werden.
3. Auf den Container kann als Array zugegriffen werden, um die übergebenen Parameter zu erhalten. Zum Beispiel: $this[‘mailer.class’]
Die Dienstleistungsmarke muss eindeutig sein und darf nur aus Buchstaben, Zahlen, „_“ und „.“ bestehen. „.“ kann als Namespace verwendet werden (z. B. mail.mailer und mail.transport).

Jetzt wollen wir sehen, wie dieser neue Container verwendet wird

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;
Nach dem Login kopieren

Da die Container-Klasse sfServiceContainer erbt, wird die Schnittstelle sehr übersichtlich.

Der Zugriff auf den Dienst erfolgt über die einheitliche Schnittstelle

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

Eine einfachere Möglichkeit besteht darin, auf den Dienst über Attribute zuzugreifen

if (isset($sc->mailer))
{
  $mailer = $sc->mailer;
}
$sc->mailer = $mailer;
Nach dem Login kopieren
Der Zugriff auf die Parameter erfolgt über die einheitliche Schnittstelle Schnittstelle
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);
Nach dem Login kopieren

Auf Parameter kann auch wie Arrays über Container zugegriffen werden

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

Container können als Iteratoren zum Durchlaufen aller Dienste betrachtet werden

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

Wenn nicht viele Dienste verwaltet werden müssen, Sie aber dennoch viel grundlegende Arbeit leisten und viel Code kopieren müssen, müssen Sie zugeben, dass Sie sfServiceContainer verwenden ist sehr nützlich.
Wenn die Anzahl der zu verwaltenden Dienste immer größer wird, muss es eine bessere Möglichkeit geben, die Dienste zu beschreiben.
Aus diesem Grund verwenden wir die sfServiceContainer-Klasse meistens nicht direkt. Dennoch ist es notwendig, einige Zeit damit zu verbringen, darüber zu sprechen, da es ein wichtiger Eckpfeiler des Dependency-Injection-Containers von Symfony ist.

Das Obige ist der Inhalt der PHP-Abhängigkeitsinjektionscontainerserie (3) Symfony. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage