{"id":12605,"date":"2016-05-25T16:15:27","date_gmt":"2016-05-25T13:15:27","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=12605"},"modified":"2018-01-09T10:54:58","modified_gmt":"2018-01-09T08:54:58","slug":"php-dependency-injection-tutorial","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/","title":{"rendered":"PHP Dependency Injection Tutorial"},"content":{"rendered":"<p>Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language with are working with allows us. Fortunately, PHP provides the tools to implement it.<\/p>\n<p>This is a tutorial of how to deal with Dependency Injection in PHP, looking at the advantages that Dependency Injection supposes, and checking out different ways and tools to implement it.<\/p>\n<p>For this tutorial, we will use:<\/p>\n<ul>\n<li>Ubuntu (14.04) as Operating System.<\/li>\n<li>Apache HTTP server (2.4.7).<\/li>\n<li>PHP (5.5.9).<\/li>\n<li>SQLite3, as an example of a dependency to inject.<\/li>\n<li>Composer PHP dependency manager.<\/li>\n<\/ul>\n<p>&nbsp;<br \/>\n[ulp id=&#8217;8njY7i2QRy6sg8pg&#8217;]<\/p>\n<div class=\"toc\">\n<h3>Table Of Contents<\/h3>\n<dl>\n<dt><a href=\"#section_1\">1. Preparing the environment<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#section_1_1\">1.1. Installation<\/a><\/dt>\n<dt><a href=\"#section_1_2\">1.2. PHP Configuration<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#section_2\">2. Introduction to Dependency Injection (DI)<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#section_2_1\">2.1. What is Dependency Injection?<\/a><\/dt>\n<dt><a href=\"#section_2_2\">2.2. How does DI help us?<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#section_3\">3. A non-DI example<\/a><\/dt>\n<dt><a href=\"#section_4\">4. First approach to DI: manual injection<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#section_4_1\">4.1. Defining the interface<\/a><\/dt>\n<dt><a href=\"#section_4_2\">4.2. Implementing the interface<\/a><\/dt>\n<dt><a href=\"#section_4_3\">4.3. Accessing the interface<\/a><\/dt>\n<dt><a href=\"#section_4_4\">4.4. Instantiating interface implementations<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#section_5\">5. Second approach to DI: Injector class<\/a><\/dt>\n<dd><a href=\"#section_5_1\">5.1. Creating the injector<\/a><\/dd>\n<dd><a href=\"#section_5_2\">5.2. Calling the injector<\/a><\/dd>\n<dt><a href=\"#section_6\">6. PHP-DI<\/a><\/dt>\n<dd><a href=\"#section_6_1\">6.1. Installation<\/a><\/dd>\n<dd><a href=\"#section_6_2\">6.2. The Injection Container<\/a><\/dd>\n<dd><a href=\"#section_6_3\">6.3. Injecting with annotations<\/a><\/dd>\n<dd><a href=\"#section_6_4\">6.4. Injecting with PHP definitions<\/a><\/dd>\n<dt><a href=\"#section_7\">7. Chaining dependency injections: a more thorough and complete example<\/a><\/dt>\n<dd><a href=\"#section_7_1\">7.1. Directory structure<\/a><\/dd>\n<dd><a href=\"#section_7_2\">7.2. Storage dependency&#8217;s Language dependency<\/a><\/dd>\n<dd><a href=\"#section_7_3\">7.3. Injecting the Language dependency to Storage<\/a><\/dd>\n<dd><a href=\"#section_7_4\">7.4. Defining the injection<\/a><\/dd>\n<dd><\/dd>\n<dt><a href=\"#section_8\">8. Summary<\/a><\/dt>\n<dt><a href=\"#section_9\">9. Download the source code<\/a><\/dt>\n<\/dl>\n<\/div>\n<div class=\"tip\"><strong>Tip<\/strong><br \/>\nYou may skip environment preparation and jump directly to the <a href=\"#section_2\"><strong>beginning of the tutorial<\/strong><\/a> below.<\/div>\n<h2 id=\"section_1\">1. Preparing the environment<\/h2>\n<h3 id=\"section_1_1\">1.1. Installation<\/h3>\n<p>Below, commands to install Apache, PHP and SQLite are shown:<\/p>\n<pre class=\"brush:bash\">sudo apt-get update\r\nsudo apt-get install apache2 php5 libapache2-mod-php5 php5-sqlite\r\nsudo service apache2 restart<\/pre>\n<p>To install Composer, we need to download the PHP archive from its website, and move to it to binary files directory to execute it globally:<\/p>\n<pre class=\"brush:bash\">curl -sS https:\/\/getcomposer.org\/installer | php\r\nsudo mv composer.phar \/usr\/local\/bin\/composer<\/pre>\n<h3 id=\"section_1_2\">1.2. PHP Configuration<\/h3>\n<p>In \/etc\/php5\/apache2\/php.ini file, we need to include the SQLite extension, in order to use it:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>\/etc\/php5\/apache2\/php.ini<\/em><\/span><\/p>\n<pre class=\"brush:bash\">extension=sqlite.so<\/pre>\n<p>Don&#8217;t forget to restart Apache after doing any change.<\/p>\n<h2 id=\"section_2\">2 Introduction to DI<\/h2>\n<h3 id=\"section_2_1\">2.1. What is Dependency Injection (DI)?<\/h3>\n<p>Dependency Injection is a design pattern where we <strong>supply a class (a client) the object instances it needs (the dependency), instead of instantiating itself<\/strong>. This pattern is based in a principle known as <strong>Dependency Inversion Principle<\/strong> (DIP). This principle says, basically, that <strong>high level modules should not depend directly on low level modules<\/strong>, where low level modules are those that implement basic operations; and high level modules, which use those modules for a specific purpose (what we call business logic).<\/p>\n<p>The aim of DIP, conceptually, is to change from:<\/p>\n<blockquote><p><em>A<\/em> needs to create, or use, <em>B<\/em>, in order to do <em>C<\/em><\/p><\/blockquote>\n<p>To:<\/p>\n<blockquote><p><em>A<\/em> needs <strong><em>something<\/em><\/strong> that allows doing <em>C<\/em><\/p><\/blockquote>\n<p>What <em>A<\/em> wants is to do <em>C<\/em>, no matter how. The following diagram illustrates how Dependency Injection does this:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/05\/dependeny-injection.jpg\" \/><\/p>\n<p>Let&#8217;s describe each component:<\/p>\n<ul>\n<li>The class <code>Client<\/code> uses an interface, where some methods are described. This aggregation relation describes what we defined above as <em>needs something that allows doing something<\/em>. That interface allows to do an operation. The client doesn&#8217;t know how will be it done, but it can do it.<\/li>\n<li>As said before, our interface <code>DependencyInterface<\/code> defines a set of methods. Definition means only method name, receiving parameters and returning type (this last actually not important in languages like PHP). This interface will be implemented by the dependencies that are going to be injected.<\/li>\n<li>We have, in this case, <code>DependencyA<\/code> and <code>DependencyB<\/code> specific implementations of <code>DependencyInterface<\/code> definitions. Each dependency will implement the <code>operation()<\/code> method according to its nature.<\/li>\n<li>The <code>Injector<\/code> is the component which will instantiate the required dependency, to inject it into the <code>Client<\/code>. The <code>Client<\/code> won&#8217;t know what is receiving; it will use the implementation decided by the <code>Injector<\/code>.<\/li>\n<\/ul>\n<p>Remember that DI and DIP are not equivalent, but that DI follows the DIP.<\/p>\n<h3 id=\"section_2_2\">2.2. How does DI help us?<\/h3>\n<ul>\n<li>Responsibility division: each dependency can be developed individually; the <strong>only restriction is the interface it must implement<\/strong>, which has to be agreed before. This allows to divide the work between developers, <strong>avoiding problems at integration time<\/strong>.<\/li>\n<li>Maintainable code: does one of the features need changes or fixes? With DI, we <strong>target immediately the piece of code susceptible for changes<\/strong>, and we will be sure that the changes will have to be done <strong>only in that piece of code<\/strong>.<\/li>\n<li>Reusable code: Dependency Injection makes us to design independent pieces of code (the dependencies), which <strong>can be reused as many times as we want, without repeating the code<\/strong>.<\/li>\n<li>Testeable code: <strong>without DI, testing is much more complicated<\/strong>. Why? Because, without DI, if we testing a component that is using another compontent that is not being injected, it will actually use that component in the test. In most of the cases, this is not interesting, because we would be testing several times the same thing. <strong>With Dependency Injection, we can easily mock the dependencies to test better and faster<\/strong>.<\/li>\n<\/ul>\n<p>To put all this in context, let&#8217;s see an example.<\/p>\n<h2 id=\"section_3\">3. A non-DI example<\/h2>\n<p>Let&#8217;s consider the following scenario: we are going to develop a system that inserts and reads data.<\/p>\n<p>The very first version, will work with a simple text file. So, we would have the following class to deal with the text file:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Textfile.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">&lt;?php\r\n\r\n\/**\r\n\u00a0* Methods for text file handling.\r\n\u00a0*\/\r\nclass Textfile {\r\n\r\n\u00a0\u00a0\u00a0 const TEXTFILE = 'data.txt';\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Writes the data into the textfile.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @param $data The data to write into the textfile.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function writeData($data) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 file_put_contents(self::TEXTFILE, $data . '&lt;br&gt;', FILE_APPEND);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Reads the data from the textfile.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @return Textfile data.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function readData() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $data = file_get_contents(self::TEXTFILE);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return $data;\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>And, then, a script to use this class:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[3,27,31,38]\">&lt;?php\r\n\r\nrequire_once('Textfile.php');\r\n\r\ndefine('ACTION_READ', 'read');\r\ndefine('ACTION_WRITE', 'write');\r\ndefine('WRITE_DATA', 'data');\r\n\r\n\/**\r\n\u00a0* Checks if the given parameters are set. If one of the specified parameters is not set,\r\n\u00a0* die() is called.\r\n\u00a0*\r\n\u00a0* @param $parameters The parameters to check.\r\n\u00a0*\/\r\nfunction checkGETParametersOrDie($parameters) {\r\n\u00a0\u00a0 \u00a0foreach ($parameters as $parameter) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0isset($_GET[$parameter]) || die(\"Please, provide '$parameter' parameter.\");\r\n\u00a0\u00a0 \u00a0}\r\n}\r\n\r\n\/\/ Flow starts here.\r\n\r\ncheckGETParametersOrDie(['action']);\r\n\r\n$action = $_GET['action'];\r\n\r\n$textfile = new Textfile();\r\n\r\nswitch ($action) {\r\n\u00a0\u00a0 \u00a0case ACTION_READ:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$response = $textfile-&gt;readData();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0break;\r\n\r\n\u00a0\u00a0 \u00a0case ACTION_WRITE:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0checkGETParametersOrDie([WRITE_DATA]);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$data = $_GET[WRITE_DATA];\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$textfile-&gt;writeData($data);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$response = 'Data written.';\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0break;\r\n\r\n\u00a0\u00a0 \u00a0default:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$response = 'Please, provide a valid \"' . WRITE_DATA . '\" parameter.';\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0break;\r\n}\r\n\r\necho $response;<\/pre>\n<p>Nothing really special: we include the required <code>Textfile<\/code> class in line 3, we instantiate it in line 27, and we call its methods in lines 31 and 38, depending on what we are going to do.<\/p>\n<p>As time goes by, we realize that a text file is no longer a suitable option because we need something more sophisticated; a relational database. So, we would develop another class to deal with the database:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>DB.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">&lt;?php\r\n\r\n\/**\r\n\u00a0* Methods for database handling.\r\n\u00a0*\/\r\nclass DB extends SQLite3 {\r\n\r\n\u00a0\u00a0 \u00a0const DATABASE = 'data.db';\r\n\r\n\u00a0\u00a0 \u00a0\/**\r\n\u00a0\u00a0 \u00a0 * DB class constructor. Initialize method is called, which will create data table if\r\n\u00a0\u00a0 \u00a0 * it does not exist already.\r\n\u00a0\u00a0 \u00a0 *\/\r\n\u00a0\u00a0 \u00a0public function __construct() {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$this-&gt;open(self::DATABASE);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$this-&gt;initialize();\r\n\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0\/**\r\n\u00a0\u00a0 \u00a0 * Craetes the table if it does not exist already.\r\n\u00a0\u00a0 \u00a0 *\/\r\n\u00a0\u00a0 \u00a0protected function initialize() {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$sql = 'CREATE TABLE IF NOT EXISTS data (\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0data STRING\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0)';\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$this-&gt;exec($sql);\r\n\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0\/**\r\n\u00a0\u00a0 \u00a0 * Inserts the data into the databse.\r\n\u00a0\u00a0 \u00a0 *\r\n\u00a0\u00a0 \u00a0 * @param $data Data to insert.\r\n\u00a0\u00a0 \u00a0 *\/\r\n\u00a0\u00a0 \u00a0public function insertData($data) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$sql = 'INSERT INTO data\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0VALUES (:data)';\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$statement = $this-&gt;prepare($sql);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$statement-&gt;bindValue(':data', $data);\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$statement-&gt;execute();\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$statement-&gt;close();\r\n\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0\/**\r\n\u00a0\u00a0 \u00a0 * Selects data from database.\r\n\u00a0\u00a0 \u00a0 *\r\n\u00a0\u00a0 \u00a0 * @return Database data.\r\n\u00a0\u00a0 \u00a0 *\/\r\n\u00a0\u00a0 \u00a0public function selectData() {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$sql = 'SELECT data\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0FROM\u00a0\u00a0 data';\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$results = $this-&gt;query($sql);\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$data = '';\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0while ($row = $results-&gt;fetchArray()) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$data .= $row['data'] . '&lt;br&gt;';\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return $data;\r\n\u00a0\u00a0 \u00a0}\r\n}<\/pre>\n<p>And now, we have to update our <code>Controller.php<\/code> file, in order to use our brand-new <code>DB<\/code> class:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[3,26,30,37]\">&lt;?php\r\n\r\nrequire_once('DB.php');\r\n\r\ndefine('ACTION_READ', 'read');\r\ndefine('ACTION_WRITE', 'write');\r\ndefine('WRITE_DATA', 'data');\r\n\r\n\/**\r\n\u00a0* Checks if the given parameters are set. If one of the specified parameters is not set,\r\n\u00a0* die() is called.\r\n\u00a0*\r\n\u00a0* @param $parameters The parameters to check.\r\n\u00a0*\/\r\nfunction checkGETParametersOrDie($parameters) {\r\n\u00a0\u00a0 \u00a0foreach ($parameters as $parameter) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0isset($_GET[$parameter]) || die(\"Please, provide '$parameter' parameter.\");\r\n\u00a0\u00a0 \u00a0}\r\n}\r\n\r\n\/\/ Flow starts here.\r\ncheckGETParametersOrDie(['action']);\r\n\r\n$action = $_GET['action'];\r\n\r\n$db = new DB();\r\n\r\nswitch ($action) {\r\n\u00a0\u00a0 \u00a0case ACTION_READ:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$response = $db-&gt;selectData();\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0break;\r\n\r\n\u00a0\u00a0 \u00a0case ACTION_WRITE:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0checkGETParametersOrDie([WRITE_DATA]);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$data = $_GET[WRITE_DATA];\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$db-&gt;insertData($data);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$response = 'Data written.';\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0break;\r\n\r\n\u00a0\u00a0 \u00a0default:\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0$response = 'Please, provide a valid \"action\" parameter.';\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0break;\r\n}\r\n\r\necho $response;<\/pre>\n<p>Let&#8217;s see carefully what has happened:<\/p>\n<ul>\n<li>The file requirement and the instance have changed. Well, this is something that must be done somewhere.<\/li>\n<li>Here is the important part: <strong>every object method call has changed<\/strong>. Apart from the object name itself, the methods have changed. Why? Because <strong>we have not forced to the <code>Textfile<\/code> and <code>DB<\/code> classes to share the same interface<\/strong>. And, in this case, we are lucky that the only thing that has changed is the name, and not the parameters, or the return type.<\/li>\n<li>There is another thing to take into account: how shall we test <code>Controller.php<\/code>? Currently, is using the <code>DB<\/code> class. If we test it, we are using the real database. For example, the database could be that big that could make the tests quite slow.<\/li>\n<\/ul>\n<p>This have been affordable changes, we just changed a few lines. But imagine this problem in a real project, with several dependencies and developers. This can be a real problem not only for maintaining, but at development also.<\/p>\n<h2 id=\"section_4\">4. First approach to DI: manual injection<\/h2>\n<p>Let&#8217;s resolve this <strong>adding an abstraction layer between our components<\/strong>.<\/p>\n<p>The first step must be to ask ourselves:<\/p>\n<blockquote><p><strong>What<\/strong> do we want to offer?<\/p><\/blockquote>\n<p>In this case is pretty clear. We want to offer methods for reading and writing. <strong>It doesn&#8217;t matter how, from where, or any other implementation details<\/strong>. We only focus in what.<\/p>\n<h3 id=\"section_4_1\">4.1. Defining the interface<\/h3>\n<p>For that, as in other Object Oriented Programming languages, we have the <strong>Interfaces<\/strong>. Object interfaces allow to specify which methods have to be implemented by a class, without defining how are going to be implemented.<\/p>\n<p>So, lets define an interface for our read and write purposes:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageInterface.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">&lt;?php\r\n\r\n\/**\r\n\u00a0* Interface for method definitions for dealing with storage.\r\n\u00a0*\/\r\ninterface StorageInterface {\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Writes the given data into the storage.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @param $data The data to write.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function writeData($data);\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Reads the data from the storage.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @return The read data from storage.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function readData();\r\n}<\/pre>\n<p>So simple. We just define the methods inside an <code>interface<\/code> piece of code. Now, we will implement it in our classes.<\/p>\n<h3 id=\"section_4_2\">4.2. Implementing the interface<\/h3>\n<p><span style=\"text-decoration: underline;\"><em>Textfile.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[3,8,17,26]\">&lt;?php\r\n\r\nrequire_once('StorageInterface.php');\r\n\r\n\/**\r\n\u00a0* Methods for text file handling.\r\n\u00a0*\/\r\nclass Textfile implements StorageInterface {\r\n\r\n\u00a0\u00a0\u00a0 const TEXTFILE = 'data.txt';\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Writes the data into the textfile.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @param $data The data to write into the textfile.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function writeData($data) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 file_put_contents(self::TEXTFILE, $data . '&lt;br&gt;', FILE_APPEND);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Reads the data from the textfile.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @return Textfile data.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function readData() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $data = file_get_contents(self::TEXTFILE);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return $data;\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>The interfaces are implemented with implements keyword. There are some things that we must know about interfaces:<\/p>\n<ul>\n<li>A class that implements an interface, needs to implement every method defined in that interface. Otherwise, a PHP fatal error will be thrown.<\/li>\n<li>The implemented methods must have the same name and parameters as the function defined in the interface.<\/li>\n<\/ul>\n<p>Let&#8217;s do the same with DB class:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>DB.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[3,8,37,54]\">&lt;?php\r\n\r\nrequire_once('StorageInterface.php');\r\n\r\n\/**\r\n\u00a0* Methods for database handling.\r\n\u00a0*\/\r\nclass DB extends SQLite3 implements StorageInterface{\r\n\r\n\u00a0\u00a0\u00a0 const DATABASE = 'data.db';\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * DB class constructor. Initialize method is called, which will create data table if\r\n\u00a0\u00a0\u00a0\u00a0 * it does not exist already.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function __construct() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $this-&gt;open(self::DATABASE);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $this-&gt;initialize();\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Craetes the table if it does not exist already.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 protected function initialize() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $sql = 'CREATE TABLE IF NOT EXISTS data (\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 data STRING\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )';\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $this-&gt;exec($sql);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Inserts the data into the databse.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @param $data Data to insert.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function writeData($data) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $sql = 'INSERT INTO data\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 VALUES (:data)';\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $statement = $this-&gt;prepare($sql);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $statement-&gt;bindValue(':data', $data);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $statement-&gt;execute();\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $statement-&gt;close();\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Selects data from database.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @return Database data.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function readData() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $sql = 'SELECT data\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FROM\u00a0\u00a0 data';\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $results = $this-&gt;query($sql);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $data = '';\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 while ($row = $results-&gt;fetchArray()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $data .= $row['data'] . '&lt;br&gt;';\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return $data;\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>Note that we have changed the method names (lines 37 and 54) to coincide with those defined in the interface.<\/p>\n<p>Nothing really exciting for the moment, right? Actually, some can think that we have done anything new.<\/p>\n<h3 id=\"section_4_3\">4.3. Accessing the interface<\/h3>\n<p>Instead of accessing the implementations directly in <code>Controller.php<\/code>, as in the non-DI example, we are going to create a wrapper for it, where the dependencies will be injected:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php<\/em><\/span><\/p>\n<pre class=\"brush:php;highlight:[3,17,18,27,36]\">&lt;?php\r\n\r\nrequire_once('StorageInterface.php');\r\n\r\n\/**\r\n\u00a0* StorageInterface wrap.\r\n\u00a0*\/\r\nclass StorageHandler {\r\n\r\n\u00a0\u00a0\u00a0 protected $storage;\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * StorageHandler constructor, with an implementation of StorageInterface.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @param $storage StorageInterface implementation.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function __construct(StorageInterface $storage) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $this-&gt;storage = $storage;\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Writes the data using the storage implementation.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @param $data Data to write.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function writeData($data) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $this-&gt;storage-&gt;writeData($data);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * Reads the data using the storage implementation.\r\n\u00a0\u00a0\u00a0\u00a0 *\r\n\u00a0\u00a0\u00a0\u00a0 * @return Read data.\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function readData() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $data = $this-&gt;storage-&gt;readData();\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return $data;\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>This is the class that deals with data reading and writing. But it only knows about an interface, which has methods that are not implemented. The key is that <strong>it will receive a concrete implementation in the constructor,<\/strong> <strong>and we save it as an attribute of the class<\/strong> (lines 17, 18). We even specify that it must receive an implementation of <code>StorageInterface<\/code>, even if in PHP is not necessary to declare types. But, in this cases, is a good practice to specify the interface we are expecting, to express that we will receive an unknown implementation of that interface.<\/p>\n<p>So, when we call those methods (lines 27, 36), we will be calling received instance&#8217;s implemented methods. What they do is not important, the only thing the class has to know is that it will have methods named as defined in the interface.<\/p>\n<p>We don&#8217;t have to even require those specific implementations classes, is enough to require only the interface (line 3).<\/p>\n<p>We could even add the possibility to change that implementation on runtime!<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">public function setStorage(StorageInterface $storage) {\r\n\u00a0\u00a0\u00a0 $this-&gt;storage = $storage;\r\n}<\/pre>\n<p>Adding a setter, we could change the implementation <code>StorageHandler<\/code> class is using at any time.<\/p>\n<h3 id=\"section_4_4\">4.4. Instantiating interface implementations<\/h3>\n<p>Last step is to control the <code>StorageHandler<\/code>:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[3,4,27,28]\">&lt;?php\r\n\r\nrequire_once('StorageHandler.php');\r\nrequire_once('Textfile.php');\r\n\r\ndefine('ACTION_READ', 'read');\r\ndefine('ACTION_WRITE', 'write');\r\ndefine('WRITE_DATA', 'data');\r\n\r\n\/**\r\n\u00a0* Checks if the given parameters are set. If one of the specified parameters is not set,\r\n\u00a0* die() is called.\r\n\u00a0*\r\n\u00a0* @param $parameters The parameters to check.\r\n\u00a0*\/\r\nfunction checkGETParametersOrDie($parameters) {\r\n\u00a0\u00a0\u00a0 foreach ($parameters as $parameter) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isset($_GET[$parameter]) || die(\"Please, provide '$parameter' parameter.\");\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n\r\n\/\/ Flow starts here.\r\ncheckGETParametersOrDie(['action']);\r\n\r\n$action = $_GET['action'];\r\n\r\n$storage = new Textfile();\r\n$handler = new StorageHandler($storage);\r\n\r\nswitch ($action) {\r\n\u00a0\u00a0\u00a0 case ACTION_READ:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $response = $handler-&gt;readData();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\r\n\u00a0\u00a0\u00a0 case ACTION_WRITE:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 checkGETParametersOrDie([WRITE_DATA]);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $data = $_GET[WRITE_DATA];\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $handler-&gt;writeData($data);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $response = 'Data written.';\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\r\n\u00a0\u00a0\u00a0 default:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $response = 'Please, provide a valid \"action\" parameter.';\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n}\r\n\r\necho $response;<\/pre>\n<p>As in the first case in the previous approach without DI, we suppose that we are going to use the text file as storage. So, we require it (line 4), we instantiate it (line 27), and instantiate the <code>StorageHandler<\/code> class passing the <code>Textfile<\/code> implementation in the constructor (line 28). Or, in other words: <strong>we are injecting the <code>Textfile<\/code> dependency to <code>StorageHandler<\/code><\/strong>.<\/p>\n<p>Now, let&#8217;s say that we want to use the database. The changes would be:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">\/\/...\r\n\r\nrequire_once('DB.php');\r\n\r\n\/\/ ...\r\n\r\n$storage = new DB();<\/pre>\n<p>And that&#8217;s it. The <code>$handler<\/code> object will be working without the need of suffering any changes. We just include the new class, and we change the instance of the variable passed to <code>StorageHandler<\/code> instantiation; <strong>the injected dependency, now, is <code>DB<\/code><\/strong>.<\/p>\n<p>Isn&#8217;t it amazing?<\/p>\n<h2 id=\"section_5\">5. Second approach to DI: Injector class<\/h2>\n<p>In the first approach, we have seen how to perform a Dependency Injection, in such a disorganized way: we only have to change the instantiating class, yes, but we have to know exactly where is being instantiated. And this may not be easy in medium-large sized projects &#8211; in this case, we have only a dependency, but imagine finding each injection for tens of dependencies.<\/p>\n<p>So, let&#8217;s create a completely isolated wrapper for the injection to <code>StorageHandler<\/code> &#8211; just as in the diagram we saw in section 1.1.<\/p>\n<h3 id=\"section_5_1\">5.1. Creating the injector<\/h3>\n<p>As said, let&#8217;s define a class only for instantiating the dependency for <code>StorageHandler<\/code>:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageInjector.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">&lt;?php\r\n\r\nrequire_once('Textfile.php');\r\n\/**\r\n\u00a0* Storage dependency injector.\r\n\u00a0*\/\r\nclass StorageInjector {\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0 \u00a0 * Retrieves the specified instance of StorageInterface.\r\n\u00a0\u00a0 \u00a0 *\r\n\u00a0\u00a0 \u00a0 * @return StorageInterface implementation.\r\n\u00a0\u00a0 \u00a0 *\/\r\n\u00a0\u00a0 \u00a0public static function getStorageInstance() {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return new Textfile();\r\n\u00a0\u00a0 \u00a0}\r\n}<\/pre>\n<p>So simple, just a function that retrieves the defined instance. We have defined as a static function, because there&#8217;s no real need to instantiate this class.<\/p>\n<h3 id=\"section_5_2\">5.2. Calling the injector<\/h3>\n<p>Now, the only thing we have to do is to pass the returned object by <code>StorageInjector::getStorageInstance()<\/code> to <code>StorageHandler<\/code> constructor:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">$handler = new StorageHandler(StorageInjector::getStorageInstance());<\/pre>\n<p>And the <code>StorageHandler<\/code> will use the <strong>whatever dependency injected by the StorageInjector, which will have the responsibility of deciding the dependency to inject<\/strong>.<\/p>\n<p>So, now, if we have to inject the <code>DB<\/code> dependency, we exactly know where to change that injection:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageInjector.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">public static function getStorageInstance() {\r\n\u00a0\u00a0 \u00a0return new DB();\r\n}<\/pre>\n<p>Including, of course, the file where DB is defined.<\/p>\n<p>We say that we will exactly know the location of the injection because we are supposing that <strong>we are looking for a Injector suffixed file, or any other agreed standard for injector files<\/strong>.<\/p>\n<h2 id=\"section_6\">6. PHP-DI<\/h2>\n<p>The PHP community is so great. It is constantly developing useful components. And Dependency Injection is not an exception: PHP-DI. In this chapter we will see how we can use it.<\/p>\n<h3 id=\"section_6_1\">6.1. Installation<\/h3>\n<p>The installation is so simple, thanks to our beloved Composer. Just enter the following command in your working directory:<\/p>\n<pre class=\"brush:bash\">composer require php-di\/php-di<\/pre>\n<p>And it will download the required stuff. Note that a composer.json and composer.lock, and a vendor directory have been created. Don&#8217;t touch them. The first two define the component we are using, and the vendor folder contains the PHP-CI code itself.<\/p>\n<h3 id=\"section_6_2\">6.2. The Injection Container Container<\/h3>\n<p>PHP-CI uses a concept called container for the dependency injection, using a technique named <em>autowiring<\/em>, inspired by Java&#8217;s Spring framework. Let&#8217;s see how it works.<\/p>\n<p>First, in the Controller.php file, we need to require a new file in order to use PHP-CI&#8217;s classes:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">require_once('vendor\/autoload.php');\r\n\r\n\/\/ ...<\/pre>\n<p>Then, we will replace the following lines:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">\/\/ ...\r\n\r\n$storage = new Textfile();\r\n$handler = new StorageHandler($storage);\r\n\r\n\/\/ ...<\/pre>\n<p>With the following:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">\/\/ ...\r\n$container = DI\\ContainerBuilder::buildDevContainer();\r\n$handler = $container-&gt;get('Textfile');\r\n\r\n\/\/ ...<\/pre>\n<p>What <code>$container-&gt;get()<\/code> does is, actually, create both <code>Textfile<\/code> and <code>StorageHandler<\/code> instances. The container uses the above mentioned <em>autowiring<\/em> technique to inject a <code>Textfile<\/code> object to the <code>StorageHandler<\/code> object.<\/p>\n<p>This is actually not very impressive. We could say that even has complicated more the things.<\/p>\n<p>But this is not the only way PHP-CI allows us to inject dependency, and is actually quite limited &#8211; it is not able to resolve dependencies that have parameters in the constructor. Let&#8217;s see more interesting ways.<\/p>\n<h3 id=\"section_6_3\">6.3. Injecting with annotations<\/h3>\n<p>In order to use this feature, first, we need Doctrine Annotations library, so, we will install it via Composer:<\/p>\n<pre class=\"brush:bash\">composer require doctrine\/annotations<\/pre>\n<p>Apart from that, we also have to make sure that, in <code>php.ini<\/code>, we have the following directive set to <code>1<\/code>:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>\/etc\/php5\/apache2\/php.ini<\/em><\/span><\/p>\n<pre class=\"brush:bash\">opcache.load_comments=1<\/pre>\n<p>Don&#8217;t forget to restart Apache after doing any changes.<\/p>\n<p>To use the annotations, we have to construct the container in a different way. First, we need a <code>ContainerBuilder<\/code> instance, to configure it to use the annotations.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">\/\/ ...\r\n\r\n$containerBuilder = new DI\\ContainerBuilder();\r\n$containerBuilder-&gt;useAnnotations(true);\r\n$container = $containerBuilder-&gt;build();\r\n\r\n\/\/ ...<\/pre>\n<p>Note that, in this case, we have constructed the container in a different way: first, creating the container builder, and then, creating the container using this container builder instance. This is necessary, because we need to configure the container builder to use the annotations.<\/p>\n<p>Now, let&#8217;s inject our dependency using the annotation. We will begin injecting the <code>Textfile<\/code> dependency:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php <\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[13]\">&lt;?php\r\n\r\nrequire_once('StorageInterface.php');\r\n\r\n\/**\r\n\u00a0* StorageInterface wrap.\r\n\u00a0*\r\nclass StorageHandler {\r\n\r\n\u00a0\u00a0\u00a0 private $storage;\r\n\r\n\u00a0\u00a0\u00a0 \/**\r\n\u00a0\u00a0\u00a0\u00a0 * @Inject({\"Textfile\"})\r\n\u00a0\u00a0\u00a0\u00a0 *\/\r\n\u00a0\u00a0\u00a0 public function __construct(StorageInterface $storage) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $this-&gt;storage = $storage;\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 \/\/ ...\r\n}<\/pre>\n<p>As you can see in the line 10, we add an <code>@Inject<\/code> annotation in the PHP DocBlock, specifying the dependency we are injecting.<\/p>\n<p>It would be possible to inject several dependencies:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[10]\">\/\/ ...\r\n\r\n\/**\r\n * @Inject({\"Textfile\", \"WhateverDependency\"})\r\n *\/\r\npublic function __construct(StorageInterface $storage, Dependency $anotherDependency) {\r\n\u00a0\u00a0\u00a0 \/\/ ...\r\n}<\/pre>\n<p>There is the possibility also to specify the injection of each parameter, specifying the name:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[10]\">\/\/ ...\r\n\r\n\/**\r\n * @Inject({\"storage\" = \"Textfile\", \"anotherDependency\" = \"WhateverDependency\"})\r\n *\/\r\npublic function __construct(StorageInterface $storage, Dependency $anotherDependency) {\r\n\u00a0\u00a0\u00a0 \/\/ ...\r\n}<\/pre>\n<p>This injection method is definitively better than previously seen <em>autowiring<\/em>: we can specify several dependencies; and the injection is made in an isolated way, in the class using the dependency. This allows us to have the injections in a tidier way, without the need of having Injector classes.<\/p>\n<p>But we have to do another little change before ending. When getting the instance through the container, we must specify the class were the dependency is defined:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[10]\">\/\/ ...\r\n\r\n$handler = $container-&gt;get('Handler');\r\n\r\n\/\/ ...<\/pre>\n<p>Instead of the dependency itself, as with <em>autowiring<\/em>.<\/p>\n<p>Now, to change the injected dependency, we have make the change in the class the injection is made:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageHandler.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[4]\">\/\/ ...\r\n\r\n\/**\r\n * @Inject({\"DB\"})\r\n *\/\r\npublic function __construct(StorageInterface $storage) {\r\n\u00a0\u00a0\u00a0 $this-&gt;storage = $storage;\r\n}\r\n\r\n\/\/ ...<\/pre>\n<p>The injection is organized in a more organized way than before, and much more than manually, don&#8217;t you think so?<\/p>\n<p>Unfortunately, the annotations have some limitations:<\/p>\n<ul>\n<li>Only classes can be injected, not values.<\/li>\n<li>As with <em>autowiring<\/em>, we can&#8217;t inject dependencies that are expecting parameters in the constructor.<\/li>\n<\/ul>\n<h3 id=\"section_6_4\">6.4. Injecting with PHP definitions<\/h3>\n<p>PHP-DI still offers another way to do the injections: with PHP definitions.<\/p>\n<p>Let&#8217;s define a file for the dependencies for our scenario:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>dependencies.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[7]\">&lt;?php\r\n\r\nrequire_once('vendor\/autoload.php');\r\nrequire_once('Textfile.php');\r\n\r\nreturn [\r\n\u00a0\u00a0\u00a0 'StorageInterface' =&gt; new Textfile()\r\n];<\/pre>\n<p>We are defining our <code>Textfile<\/code> class as the dependency for <code>'StorageInterface'<\/code> key in the array.<\/p>\n<p>Now, we are going to inject the dependency:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">\/\/ ...\r\n\r\n$builder = new DI\\ContainerBuilder();\r\n$builder-&gt;addDefinitions('dependencies.php');\r\n$container = $builder-&gt;build();\r\n\r\n$handler = $container-&gt;get('StorageInterface');\r\n\r\n\/\/ ...<\/pre>\n<p>And that&#8217;s it! The only thing we have to do is to specify the key of the array we defined in <code>dependencies.php<\/code>, to get its value.<\/p>\n<p>If we want to inject the <code>DB<\/code> dependency, we just change the dependency file:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>dependencies.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[7]\">&lt;?php\r\n\r\nrequire_once('vendor\/autoload.php');\r\nrequire_once('DB.php');\r\n\r\nreturn [\r\n\u00a0\u00a0\u00a0 'StorageInterface' =&gt; new DB()\r\n];<\/pre>\n<p>And the container, behind the scenes, will inject for us the <code>DB<\/code> dependency.<\/p>\n<p>In comparison with other ways of injecting, this allows us to inject the dependency in a key-value binding, which may result a more tidier way to define the injections. And we could pass parameters in the constructor with any problem.<\/p>\n<p>We could consider this injection way the most closer to a completely isolated injection solution, since we are actually defining a configuration file (yes, is PHP code, but with a configuration file format, quite close to properties files, for example), specifying the value of each dependency.<\/p>\n<h2 id=\"section_7\">7. Chaining dependency injections: a more thorough and complete example<\/h2>\n<p>We have dealed with a quite naive example: just a dependency injection. This can be a good example for starting to understand the DI pattern, but we will probably have to deal with more than one dependency in the same project.<\/p>\n<p>And it could happen that one of the dependency, requires another dependency. We will suppose that our StorageInterface needs an own dependency, and we will use the <strong>all the powerfulness of PHP-DI&#8217;s PHP definitions to deal with it<\/strong>.<\/p>\n<p>Let&#8217;s imagine that the Storage classes will need a dependency to write, along with the received data, an informative message in a language. So, it will depend on a LanguageInterface dependency to write that message.<\/p>\n<h3 id=\"section_7_1\">7.1. Directory structure<\/h3>\n<p>The project is getting bigger, and having all the sources in the same directory is not a good idea. We should organize the files in directories, taking into account the &#8220;dependency levels&#8221;.<\/p>\n<pre class=\"brush:bash\">\u251c\u2500\u2500 storage_dependencies\/\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 language_dependencies\/\r\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 English.php\r\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 LanguageInterface.php\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 DB.php\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 StorageInterface.php\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 Textfile.php\r\n\u251c\u2500\u2500 StorageHandler.php\r\n\u251c\u2500\u2500 Controller.php\r\n\u251c\u2500\u2500 dependencies.php\r\n\u251c\u2500\u2500 composer.json\r\n\u251c\u2500\u2500 composer.lock\r\n\u2514\u2500\u2500 vendor\/<\/pre>\n<p><strong>Note<\/strong>: don&#8217;t remember to install PHP-DI with Composer, as explained in section 6.1.<\/p>\n<h3 id=\"section_7_2\">7.2. Storage dependency&#8217;s Language dependency<\/h3>\n<p>Let&#8217;s create our interface for the language dependency of the Storage.<\/p>\n<p><span style=\"text-decoration: underline;\"><em>LanguageInterface.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">&lt;?php\r\n\r\ninterface LanguageInterface {\r\n\r\n\u00a0\u00a0 \u00a0public function getInfoString();\r\n\r\n}<\/pre>\n<p>We will create an implementation for this interface, for English:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>English.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">&lt;?php\r\n\r\nrequire_once('LanguageInterface.php');\r\n\r\nclass English implements LanguageInterface {\r\n\r\n\u00a0\u00a0 \u00a0public function getInfoString() {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return 'Writing data: ';\r\n\u00a0\u00a0 \u00a0}\r\n\r\n}<\/pre>\n<p>For later testing, you could implement your own <code>LanguageInterface<\/code> with the language you prefer (or another version of the <code>English<\/code> interface, if you prefer).<\/p>\n<h3 id=\"section_7_3\">7.3. Injecting the Language dependency to Storage<\/h3>\n<p>We must update our <code>StorageInterface<\/code> to inject our brand-new <code>LanguageInterface<\/code> dependency. This is how we are going to do it:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>StorageInterface.php<\/em><\/span><\/p>\n<pre class=\"brush:php;highlight:[7]\">&lt;?php\r\n\r\nrequire_once('language_dependencies\/LanguageInterface.php');\r\n\r\ninterface StorageInterface {\r\n\r\n\u00a0\u00a0 \u00a0public function __construct(LanguageInterface $language);\r\n\r\n\u00a0\u00a0\u00a0 public function writeData($data);\r\n\r\n\u00a0\u00a0\u00a0 public function readData();\r\n}<\/pre>\n<p>What we are doing is forcing every class implementing <code>StorageInterface<\/code> to have a constructor method reciving an instance of <code>LanguageInterface<\/code>. Of course, those classes will have to retrieve that parameter and save it as a class property:<\/p>\n<pre class=\"brush:php\">\/\/ ...\r\n\r\nprotected $language;\r\n\r\npublic function __construct(LanguageInterface $language) {\r\n\u00a0\u00a0\u00a0 $this-&gt;language = $language;\r\n}\r\n\r\n\/\/ ...<\/pre>\n<p>In both <code>Textfile<\/code> and <code>DB<\/code> classes.<\/p>\n<h3 id=\"section_7_4\">7.4. Defining the injection<\/h3>\n<p>Let&#8217;s create a file were the dependencies will be injected, using PHP-DI&#8217;s PHP definitions:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>dependencies.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[8,10]\">&lt;?php\r\n\r\nrequire_once('vendor\/autoload.php');\r\nrequire_once('storage_dependencies\/Textfile.php');\r\nrequire_once('storage_dependencies\/language_dependencies\/English.php');\r\n\r\nreturn [\r\n\u00a0\u00a0 \u00a0'LanguageInterface' =&gt; DI\\Object('English'),\r\n\r\n\u00a0\u00a0\u00a0 'StorageInterface' =&gt; function (LanguageInterface $language) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return new Textfile($language);\r\n\u00a0\u00a0\u00a0 }\r\n];<\/pre>\n<p>Let&#8217;s see it step by step:<\/p>\n<ul>\n<li>We require the injecting dependencies, as we have been doing every time.<\/li>\n<li>We <strong>start injecting from the inner dependency level<\/strong>. In other words, if a first dependency needs a second dependency, we start injecting that second one, and so on. In this case, we map the English implementation to the <code>LanguageInterface<\/code> dependency required by other class.<\/li>\n<li>Now, we need to inject the outer dependency, wich needs the previous defined dependency. How? With a closure, that receives the injected dependency for <code>LanguageInterface<\/code>, and then returns the instance for the injecting dependency, constructing it with the received <code>LanguageInterface<\/code> implementation.<\/li>\n<\/ul>\n<p>And that&#8217;s it! To instantiate the class receiving the <code>StorageInterface<\/code> dependency, we just have to do as in 6.4 section:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>Controller.php<\/em><\/span><\/p>\n<pre class=\"brush:php\">\/\/ ...\r\n\r\n$builder = new DI\\ContainerBuilder();\r\n$builder-&gt;addDefinitions('dependencies.php');\r\n$container = $builder-&gt;build();\r\n\r\n$handler = $container-&gt;get('StorageInterface');\r\n\r\n\/\/ ...<\/pre>\n<p>And we will have a <code>StorageHandler<\/code> instance, which will have a <code>Textfile<\/code> instance, which will have, in the same way, an <code>English<\/code> instance, as defined in <code>dependencies.php<\/code>.<\/p>\n<p>To change any of the injections, in any link of the chain, we have just to make the change in dependencies.php. A <strong>file that will be perfectly accessible<\/strong> (it&#8217;s the only file were the injections are defined, and the injection definition is the only purpose of the file), and <strong>that does not have any impact in the actual application logic, minimazing the possibilities of introducing bugs<\/strong> (well, if we declare the array incorrectly, we will get an error, inevitably).<\/p>\n<p>You may thought that the injections can be made in the following way:<\/p>\n<p><span style=\"text-decoration: underline;\"><em>dependencies.php<\/em><\/span><\/p>\n<pre class=\"brush:php; highlight:[8]\">&lt;?php\r\n\r\nrequire_once('vendor\/autoload.php');\r\nrequire_once('storage_dependencies\/DB.php');\r\nrequire_once('storage_dependencies\/language_dependencies\/English.php');\r\n\r\nreturn [\r\n    'StorageInterface' =&gt; new Textfile(new English());\r\n];<\/pre>\n<p>Which is okay and would work, but that it can be not as clear as the other way, specially if a considerable number of dependencies have to be injected.<\/p>\n<h2 id=\"section_8\">8. Summary<\/h2>\n<p>In this tutorial, we have seen why Dependency Injection is so important, and how it can help us to build maintainable and testeable software. For that, we have first created an example without using it, before using the DI, to recognize the real usefulness of this pattern.<\/p>\n<p>We have used several methods to achieve the Dependency Injections. Deciding which can be the most suitable for a project, is a decision that the developers have to take. But the most important thing is to, regardless which method is used, to follow that agreement in every part of the project, without mixing different methods of injection.<\/p>\n<h2 id=\"section_9\">9. Download the source code<\/h2>\n<p>This was a tutorial of Dependency Injection in PHP.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this example here: <a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2016\/05\/PHPDependencyInjectionTutorial.zip\"><strong>PHPDependencyInjectionTutorial<\/strong><\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language with are working with allows us. Fortunately, PHP provides the tools to implement it. This is a tutorial of how to deal with Dependency Injection in PHP, looking at the advantages &hellip;<\/p>\n","protected":false},"author":160,"featured_media":930,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[73,198,352],"class_list":["post-12605","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php","tag-dependency-injection","tag-design-patterns","tag-oop"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PHP Dependency Injection Tutorial - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PHP Dependency Injection Tutorial - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-05-25T13:15:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-01-09T08:54:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Toni\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Toni\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"24 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\"},\"author\":{\"name\":\"Toni\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966\"},\"headline\":\"PHP Dependency Injection Tutorial\",\"datePublished\":\"2016-05-25T13:15:27+00:00\",\"dateModified\":\"2018-01-09T08:54:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\"},\"wordCount\":3406,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg\",\"keywords\":[\"Dependency Injection\",\"Design Patterns\",\"OOP\"],\"articleSection\":[\"PHP\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\",\"name\":\"PHP Dependency Injection Tutorial - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg\",\"datePublished\":\"2016-05-25T13:15:27+00:00\",\"dateModified\":\"2018-01-09T08:54:58+00:00\",\"description\":\"Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/php\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"PHP Dependency Injection Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966\",\"name\":\"Toni\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g\",\"caption\":\"Toni\"},\"url\":\"https:\/\/www.webcodegeeks.com\/author\/julen-pardo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PHP Dependency Injection Tutorial - Web Code Geeks - 2026","description":"Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"PHP Dependency Injection Tutorial - Web Code Geeks - 2026","og_description":"Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language","og_url":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2016-05-25T13:15:27+00:00","article_modified_time":"2018-01-09T08:54:58+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg","type":"image\/jpeg"}],"author":"Toni","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Toni","Est. reading time":"24 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/"},"author":{"name":"Toni","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966"},"headline":"PHP Dependency Injection Tutorial","datePublished":"2016-05-25T13:15:27+00:00","dateModified":"2018-01-09T08:54:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/"},"wordCount":3406,"commentCount":2,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg","keywords":["Dependency Injection","Design Patterns","OOP"],"articleSection":["PHP"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/","url":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/","name":"PHP Dependency Injection Tutorial - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg","datePublished":"2016-05-25T13:15:27+00:00","dateModified":"2018-01-09T08:54:58+00:00","description":"Dependency Injection is a design pattern that should be followed in almost every software project, regardless of its size, and if the programming language","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/php-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/php\/php-dependency-injection-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"PHP","item":"https:\/\/www.webcodegeeks.com\/category\/php\/"},{"@type":"ListItem","position":3,"name":"PHP Dependency Injection Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966","name":"Toni","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g","caption":"Toni"},"url":"https:\/\/www.webcodegeeks.com\/author\/julen-pardo\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/12605","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/160"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=12605"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/12605\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/930"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=12605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=12605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=12605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}