Understanding PHP Dependency Injection Container Series (1) What is
This article is the first chapter of the series on the implementation of PHP dependency injection container.
Today, let’s not talk about the container (container). First, we will use some specific examples to introduce the concept of dependency injection to prove what problems the dependency injection model can solve and what benefits it can bring to developers.
If you already know the concept of dependency injection, you can skip this article.
Dependency injection may be one of the simplest design patterns I know. In many cases, you may have used dependency injection unconsciously. But it's also one of the hardest to explain. I think part of the reason is that most of the examples that introduce dependency injection lack practical meaning and are difficult to understand. Because PHP is mainly used for web development, let's first look at a simple web development example.
HTTP itself is a stateless connection protocol. In order to support the application to store user information when the client initiates a WEB request, we need to use a technology to achieve storage state interaction. Of course the easiest way is to use cookies, and a better way is PHP's built-in Session mechanism.
$_SESSION['language'] = 'fr';
The above code stores the user language in the Session variable named language, so in subsequent requests by the user, the language can be obtained through the global array $_SESSION:
$user_language = $_SESSION['language'];
Dependencies Injection is mainly used for object-oriented development. Now let us assume that we have a SessionStorage class, which encapsulates the PHP Session mechanism:
class SessionStorage { function __construct($cookieName = 'PHP_SESS_ID') { session_name($cookieName); session_start(); } function set($key, $value) { $_SESSION[$key] = $value; } function get($key) { return $_SESSION[$key]; } // ... }
There is also a User class that provides a more advanced encapsulation:
class User { protected $storage; function __construct() { $this->storage = new SessionStorage(); } function setLanguage($language) { $this->storage->set('language', $language); } function getLanguage() { return $this->storage->get('language'); } // ... }
The code is very simple, and it is also very simple to use the User class:
$user = new User(); $user->setLanguage('fr'); $user_language = $user->getLanguage();
Everything is beautiful, unless your program needs better scalability. Suppose now you want to change the COOKIE key value that saves session_id. Here are some alternative methods:
When creating a SessionStorage instance in the User class, use the string 'SESSION_ID' hard-coded in the SessionStorage constructor:
class User { function __construct() { $this->storage = new SessionStorage('SESSION_ID'); } // ... }
Set a constant outside the User class (named STORAGE_SESSION_NAME)
class User { function __construct() { $this->storage = new SessionStorage(STORAGE_SESSION_NAME); } // ... } define('STORAGE_SESSION_NAME', 'SESSION_ID');
Pass the Session name through the parameters in the User class constructor
class User { function __construct($sessionName) { $this->storage = new SessionStorage($sessionName); } // ... } $user = new User('SESSION_ID');
Still pass the Session name through the parameters in the User class constructor, but this time the parameters are in the form of an array
class User { function __construct($storageOptions) { $this->storage = new SessionStorage($storageOptions['session_name']); } // ... } $user = new User(array('session_name' => 'SESSION_ID'));
The above methods are all bad.
Hardcoding the session name in the user class does not really solve the problem. If you need to change the COOKIE key value that saves the session_id in the future, you have to modify the user class again (the User class should not care about the COOKIE key value) .
The way to use constants is also bad, causing the User class to depend on a constant setting.
It is relatively better to pass the session name through the parameters or array of the User class constructor, but it is not perfect. This interferes with the parameters of the User class constructor, because how to store the Session is not what the User class needs to care about. The User class should not be associated with them.
In addition, there is another problem that is not easy to solve: how do we change the SessionStorage class. There are many application scenarios for this, for example, you want to use a Session simulation class for testing, or you want to store the Session in a database or memory. With the current implementation, it is difficult to do this without changing the User class.
Now, let’s use dependency injection. Recall that we created the SessionStorage object inside the User class before. Now we modify it and pass the SessionStorage object through the constructor of the User class.
class User { function __construct($storage) { $this->storage = $storage; } // ... }
This is the most classic case of dependency injection, no one. Now there are some small changes to using the User class. First you need to create the SessionStorage object.
$storage = new SessionStorage('SESSION_ID'); $user = new User($storage);
Now, it is very simple to configure the session storage object, and it is also very simple to change the session storage object. All of this does not need to update the User class, reducing the coupling between business classes.
Pico Container's website describes dependency injection like this:
Dependency injection is a method of passing dependent components to a class through the class's constructor, method, or direct writing.
So dependency injection is not limited to constructor injection. Let’s take a look at several injection methods:
Constructor injection
class User { function __construct($storage) { $this->storage = $storage; } // ... }
setter method injection
class User { function setSessionStorage($storage) { $this->storage = $storage; } // ... }
Direct attribute injection
class User { public $sessionStorage; } $user->sessionStorage = $storage;
现在,大多数流行的PHP框架都采用了依赖注入的模式实现业务组件间的高内聚低耦合。
// symfony: 构造函数注入的例子 $dispatcher = new sfEventDispatcher(); $storage = new sfMySQLSessionStorage(array('database' => 'session', 'db_table' => 'session')); $user = new sfUser($dispatcher, $storage, array('default_culture' => 'en')); // Zend Framework: setter方式注入的例子 $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);
以上就是理解PHP依赖注入容器系列(一) 什么是的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

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

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

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

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,

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

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

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 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.
