1# Dependency injection container 2 3The PHP bug tracker application ships with a simplistic dependency injection 4container which can create services and retrieves configuration values. 5 6Services are one of the more frequently used objects everywhere across the 7application. For example, service for database access, utility service for 8uploading files, data generators, API clients, and similar. 9 10## Dependency injection 11 12Dependencies between classes are injected using either constructor, or via a 13method call such as setter. 14 15```php 16class Repository 17{ 18 private $pdo; 19 20 public function __construct(\PDO $pdo) 21 { 22 $this->pdo = $pdo; 23 } 24 25 public function getData(): array 26 { 27 return $this->pdo->query("SELECT * FROM table")->fetchAll(); 28 } 29} 30 31$pdo = new \PDO( 32 'mysql:host=localhost;dbname=bugs;charset=utf8', 'nobody', 'password', 33 [ 34 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, 35 \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, 36 \PDO::ATTR_EMULATE_PREPARES => false, 37 ] 38); 39 40$repository = new Repository($pdo); 41$data = $repository->getData(); 42``` 43 44The `$pdo` object in the example is a dependency which is injected via the 45constructor. 46 47Dependency injection container further provides a more efficient creation of 48such dependencies and services: 49 50```php 51$container = require_once __DIR__.'/../config/container.php'; 52 53$data = $container->get(Repository::class)->getData(); 54``` 55 56## Configuration 57 58Configuration parameters include infrastructure configuration (database 59credentials...) and application level configuration (directories locations...). 60 61```php 62// config/parameters.php 63 64return [ 65 'parameter_key' => 'value', 66 67 // ... 68]; 69``` 70 71Which can be retrieved by the container: 72 73```php 74$value = $container->get('parameter_key'); 75``` 76 77## Container definitions 78 79Each service class is manually defined: 80 81```php 82// config/container.php 83 84// New container initialization with configuration parameters defined in a file. 85$container = new Container(include __DIR__.'/parameters.php'); 86 87// Services are then defined using callables with a container argument $c. 88 89// Service with constructor arguments 90$container->set(App\Foo::class, function ($c) { 91 return new App\Foo($c->get(App\Dependency::class)); 92}); 93 94// Service with a setter method 95$container->set(App\Foo\Bar::class, function ($c) { 96 $object = new App\Foo\Bar($c->get(App\Dependency::class)); 97 $object->setFoobar('argument'); 98 99 return $object; 100}); 101 102// Dependencies can be service classes or configuration parameters 103$container->set(App\Foo\Bar::class, function ($c) { 104 return new App\Foo\Bar( 105 // Configuration parameter 106 $c->get('parameter_key')); 107 108 // Calling method from another service 109 $c->get(App\Dependency::class)->methodName(); 110 ); 111}); 112 113// Service with no dependencies 114$container->set(App\Dependency::class, function ($c) { 115 return new App\Dependency(); 116}); 117 118return $container; 119``` 120