This article discusses how to build a simple dependency injection container (DI container) PHP package. All code in the article, including PHPDoc annotations and unit tests (100% code coverage), has been uploaded to the GitHub repository and listed on Packagist.
Key points:
- Building DI containers helps developers understand the basic principles of dependency injection and the working mechanism of containers.
- DI containers have two main functions: "dependency injection" and "container". It needs to be able to instantiate and include services using constructor injection or setter injection methods.
- Symfony Dependency Injection Container can be used as a reference for creating custom containers. It divides container configuration into parameters and services, allowing secure storage of application keys.
- Creating a DI container involves creating a project directory, creating a
composer.json
file, and implementing a container interoperability interface. It also involves creating exceptions and reference classes. - Container class needs to contain methods for retrieving services, checking whether services have been defined, parsing parameters, and initializing services. It should also have a protection mechanism to prevent circular references.
Plan our dependency injection container
First, we split the "dependency injection container" into two roles: "dependency injection" and "container".
The two most commonly used methods of dependency injection are constructor injection and setter injection, that is, passing class dependencies through constructor parameters or method calls. If our container can instantiate and include services, it needs to be able to perform both operations.
To be a container, it must be able to store and retrieve instances of the service. This is a fairly simple task compared to creating a service, but it's still worth considering. The container-interop
package provides an interface that a set of containers can implement. The main interface is ContainerInterface
, which defines two methods: one for retrieving services and the other for testing whether the service is defined.
interface ContainerInterface { public function get($id); public function has($id); }
Learn other dependency injection containers
Symfony Dependency Injection Container allows us to define services in many different ways. In YAML, the configuration of the container may look like this:
parameters: # ... mailer.transport: sendmail services: mailer: class: Mailer arguments: ["%mailer.transport%"] newsletter_manager: class: NewsletterManager calls: - [setMailer, ["@mailer"]]
Symfony is very useful in how to divide container configuration into parameters and services. This allows application keys such as API keys, encryption keys, and authentication tokens to be stored in parameter files excluded from the source code repository.
In PHP, the same configuration of the Symfony dependency injection component is as follows:
use Symfony\Component\DependencyInjection\Reference; // ... $container->setParameter('mailer.transport', 'sendmail'); $container ->register('mailer', 'Mailer') ->addArgument('%mailer.transport%'); $container ->register('newsletter_manager', 'NewsletterManager') ->addMethodCall('setMailer', array(new Reference('mailer')));
By using the setMailer
object in a method call to Reference
, the dependency injection logic can detect that this value should not be passed directly, but should be replaced by the service it references in the container. This allows easy injecting PHP values and other services into the service without confusion.
Start
First, create a new project directory and create a composer.json
file that Composer can use to automatically load our class. Currently, this file only maps the SitePointContainer
namespace to the src
directory.
interface ContainerInterface { public function get($id); public function has($id); }
Next, since we will make our containers implement container interoperability interfaces, we need to have Composer download them and add them to our composer.json
file:
parameters: # ... mailer.transport: sendmail services: mailer: class: Mailer arguments: ["%mailer.transport%"] newsletter_manager: class: NewsletterManager calls: - [setMailer, ["@mailer"]]
In addition to the main ContainerInterface
, the container-interop
package also defines two exception interfaces. The first one is used for a regular exception encountered when creating a service, and the other is used when the requested service is not found. We will also add another exception to this list when the parameter requested is not found.
(The following content omits the code implementation part because the article is too long and the core logic has been described above. The complete code in the GitHub repository contains the complete implementation of exception classes, reference classes, and container classes.)
Summary
We learned how to create a simple dependency injection container, but there are many other containers that have powerful features that we haven't implemented yet!
Some dependency injection containers, such as PHP-DI and Aura.Di, provide a feature called auto-assembly. Here, the container guesses which services in the container should be injected into other services. To do this, they use the reflection API to find information about constructor parameters.
You can derive the repository as you like and add features like auto-assembly, which is a great exercise! Additionally, we keep a public list of all known derivative versions of this container so that others can see what you are doing. Simply share your work with us using the comments below and we will make sure to add it in.
You can also contact us using the comments below. Let us know what you want to clarify or explain, or any errors you find.
(The FAQs section is omitted as the content is highly duplicated from the above and is too long.)
The above is the detailed content of How to Build Your Own Dependency Injection Container. For more information, please follow other related articles on the PHP Chinese website!

Setting session cookie parameters in PHP can be achieved through the session_set_cookie_params() function. 1) Use this function to set parameters, such as expiration time, path, domain name, security flag, etc.; 2) Call session_start() to make the parameters take effect; 3) Dynamically adjust parameters according to needs, such as user login status; 4) Pay attention to setting secure and httponly flags to improve security.

The main purpose of using sessions in PHP is to maintain the status of the user between different pages. 1) The session is started through the session_start() function, creating a unique session ID and storing it in the user cookie. 2) Session data is saved on the server, allowing data to be passed between different requests, such as login status and shopping cart content.

How to share a session between subdomains? Implemented by setting session cookies for common domain names. 1. Set the domain of the session cookie to .example.com on the server side. 2. Choose the appropriate session storage method, such as memory, database or distributed cache. 3. Pass the session ID through cookies, and the server retrieves and updates the session data based on the ID.

HTTPS significantly improves the security of sessions by encrypting data transmission, preventing man-in-the-middle attacks and providing authentication. 1) Encrypted data transmission: HTTPS uses SSL/TLS protocol to encrypt data to ensure that the data is not stolen or tampered during transmission. 2) Prevent man-in-the-middle attacks: Through the SSL/TLS handshake process, the client verifies the server certificate to ensure the connection legitimacy. 3) Provide authentication: HTTPS ensures that the connection is a legitimate server and protects data integrity and confidentiality.

What’s still popular is the ease of use, flexibility and a strong ecosystem. 1) Ease of use and simple syntax make it the first choice for beginners. 2) Closely integrated with web development, excellent interaction with HTTP requests and database. 3) The huge ecosystem provides a wealth of tools and libraries. 4) Active community and open source nature adapts them to new needs and technology trends.

PHP and Python are both high-level programming languages that are widely used in web development, data processing and automation tasks. 1.PHP is often used to build dynamic websites and content management systems, while Python is often used to build web frameworks and data science. 2.PHP uses echo to output content, Python uses print. 3. Both support object-oriented programming, but the syntax and keywords are different. 4. PHP supports weak type conversion, while Python is more stringent. 5. PHP performance optimization includes using OPcache and asynchronous programming, while Python uses cProfile and asynchronous programming.

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP originated in 1994 and was developed by RasmusLerdorf. It was originally used to track website visitors and gradually evolved into a server-side scripting language and was widely used in web development. Python was developed by Guidovan Rossum in the late 1980s and was first released in 1991. It emphasizes code readability and simplicity, and is suitable for scientific computing, data analysis and other fields.


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

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Zend Studio 13.0.1
Powerful PHP integrated development environment

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

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.