DI - Dependency Injection trong PHP (ok) 😁😁😁
Last updated
Last updated
https://xuanthulab.net/di-dependency-injection-trong-php.html
C:\xampp\htdocs\wpclidemo\index.php
C:\xampp\htdocs\wpclidemo\Database.php
C:\xampp\htdocs\wpclidemo\User.php
C:\xampp\htdocs\wpclidemo\config.php
There are lots of tutorials and guides online describing dependency injection and autowiring with PHP, but as someone who’s new to this whole concept and never even implemented a dependency injection container I had a hard time getting started with using it in my PHP application. In this article, I want to give a very short and simple example of how to use PHP-DI to get started with a simple DI container.
Almost every PHP application consists of classes. We make objects and use those objects throughout our applications to tie all the logic together and make our applications work the way we want them to work, with our logic separated into classes. In order to use objects throughout our applications, we can choose to use dependency injection to pass objects around. A simple example of dependency injection:
Our dependency which is a Database class that connects to a given database:
Our User class which depends on the Database object to connect to a given database:
Now we can create a User object and inject the Database dependency into it in our index.php:
What we have done is:
We created a dependency, called Database. The Database dependency currently can only do one thing, which is connecting to a database.
We created a User class. This class can only do on thing, which is getting user data. In order to do this, the User class needs the Database dependency to connect to the database.
We created a User object, and passed a Database object (the dependency) to its constructor. By doing so, we’re injecting the Database dependency into the User object.
This looks nice, however, when your application gets more and more complicated, you end up passing around these objects from on place to another. This makes your code unreadable and hard to maintain. To fix this problem, we can use a DI Container, short for Dependency Injection Container. The DI Container is a single source of truth for all our dependencies and can automate the injection of dependencies throughout our code.
Step 1: Let’s install PHP-DI using Composer
Now we’ve included PHP-DI in our project. See https://php-di.org/ for more information about PHP-DI.
Step 2: Let’s modify our index.php and add a DI Container to it and create a User object with the Database dependency passed to it
On this line $containerBuilder->addDefinitions(__DIR__.’/config.php’);
we’re referring to a file called config.php. This file contains a list of our definitions. Consider definitions as being our dependencies (https://php-di.org/doc/definition.html).
Step 3: Let’s create our config with a list of definitions/dependencies
Here we require our classes at the top. Next, we import the Database and User classes. Last but not least, we return an array with our definitions. We use the class magic constant, as is advised by the PHP-DI documentation (https://php-di.org/doc/php-definitions.html#syntax).
As we’re doing $container->get(User::class);
in our index.php file, we’re instructing PHP-DI to employ autowiring. All dependencies will be loaded automatically, because the function signature of the User class constructor looks as follows:
PHP-DI will see that the User constructor requires a Database object and will inject that dependency automatically into each User object.
To tie it all together:
index.php
User.php
Database.php
config.php
Running this code, you should see the text “connected” on your screen. This means PHP-DI successfully injects the Database dependency into the User object and instantiates it.
With this simple example, you can start writing PHP code with a simple DI Container. Remember to add each dependency to the config.php and simply add your needed dependencies to the constructor of each class where you have dependencies, and PHP-DI will handle the rest using autowiring. In order to make autowiring work, you have to create objects by NOT using the new
keyword. Instead, use $myObjWithDependencies = $container->get(myObjWithDependencies::class);
and PHP-DI will know to check the constructor of myObjWithDependencies and inject all needed dependencies automatically.