Home php教程 PHP开发 Understanding PHP Dependency Injection Container Series (2) What you need

Understanding PHP Dependency Injection Container Series (2) What you need

Dec 28, 2016 am 10:24 AM

In the previous article, we used a specific Web case to illustrate dependency injection. Today we will talk about dependency injection container (Container). First, let us start with an important statement:

大Most of the time, when you use dependency injection to decouple components, you don't need a container.

But if you want to manage many different objects and deal with complex dependencies between objects, containers become very useful.
Remember the example in the first article? Before creating a User object, you must first create a SessionStorage object. This is not a big deal, but I still want to say that this is because you clearly know the objects it depends on before you create the object you need. If there are many objects and the dependencies are complicated (assuming that the SessionStorage class depends on the cache class, the cache class depends on the file class and the inputFilter class, and the file class depends on the stdio class), then it's a problem. . . .

$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
Copy after login

In the following articles we will introduce the way to implement containers in Symfony 2. But for now, in order to explain containers simply and clearly, we will ignore Symfony for now. The following will use an example in Zend Framework to illustrate:
Zend Framework's Zend_Mail class simplifies email management. It uses PHP's mail() function to send emails by default, but its flexibility is not good. Thankfully, this behavior can be easily changed by providing a transport class.
The following code shows how to create the Zend_Mail class and use a Gmail account to send emails

$transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
  'auth'     => 'login',
  'username' => 'foo',
  'password' => 'bar',
  'ssl'      => 'ssl',
  'port'     => 465,
));
$mailer = new Zend_Mail();
$mailer->setDefaultTransport($transport);
Copy after login

The Dependency Injection Container (Dependency Injection Container) is a large class that can instantiate and configure the various components it manages. and classes. In order to be able to do this, it must know the parameters and dependencies of the constructor methods of these classes.
The following is a hard-coded container, which still implements the work of obtaining the Zend_Mail object mentioned before:

class Container
{
  public function getMailTransport()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => 'foo',
      'password' => 'bar',
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }
  public function getMailer()
  {
    $mailer = new Zend_Mail();
    $mailer->setDefaultTransport($this->getMailTransport());
    return $mailer;
  }
}
//容器的使用也很简单
$container = new Container();
$mailer = $container->getMailer();
Copy after login

When using the container, if you need to obtain a Zend_Mail object, you do not need to know details of creating it, because all the details of creating an object instance are built into the container. Zend_Mail's dependency on the Mail_Transport class can also be automatically injected into the Zend_Mail object through the container.
Obtaining dependent objects is mainly implemented by getMailTransport(). The power of the container is achieved by this simple get call.
But if you are smart, you must have discovered the problem. There are hard codes in the container (such as the account and password information for sending emails, etc.). So we need to go a step further and add parameters to the container to make the container more useful.

class Container
{
  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()
  {
    $mailer = new Zend_Mail();
    $mailer->setDefaultTransport($this->getMailTransport());
    return $mailer;
  }
}
Copy after login

Now you can easily switch the account and password for sending emails through the parameters of the container constructor

$container = new Container(array(
  'mailer.username' => 'foo',
  'mailer.password' => 'bar',
));
$mailer = $container->getMailer();
Copy after login

If you feel that the Zend_Mail class cannot meet the current needs (for example, when testing, you need to do some logging), If you want to easily switch the mail sending class, you can also pass the class name through the parameters of the container constructor

class Container
{
  // ...
  public function getMailer()
  {
    $class = $this->parameters['mailer.class'];
    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());
    return $mailer;
  }
}
$container = new Container(array(
  'mailer.username' => 'foo',
  'mailer.password' => 'bar',
  'mailer.class'    => 'MyTest_Mail',
));
$mailer = $container->getMailer();
Copy after login

Finally, considering that the customer does not need to re-instantiate it every time when obtaining the mailer object (occupying overhead), The container should provide the same object instance every time.
Therefore, the program uses the protected static array $shared to store the first instantiated object. In the future, when the user obtains the mailer, the first instantiated object will be returned

class Container
{
  static protected $shared = array();
  // ...
  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;
  }
}
Copy after login

Container Encapsulating these basic functions, the container needs to manage the instantiation and configuration of objects. These objects themselves do not know that they are managed by the container, and they can ignore the existence of the container. This is why the container can manage any PHP class. It would be better if the object itself uses dependency injection to handle dependencies, but of course this is not necessary.

But manually creating and maintaining containers can quickly become a nightmare. The following article will describe how Symfony 2 implements containers.

The above is what you need to understand the PHP dependency injection container series (2). For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

See all articles