PHP DEPENDENCY
INJECTION
#burningkeyboards
@denis_ristic
PHP DEPENDENCY INJECTION
INTRO
‣ Dependency Injection is where components are given their
dependencies through their constructors, methods, or directly into
fields
‣ As a rule of thumb, constructor injection is best for required
dependencies, like in our example, and setter injection is best for
optional dependencies, like a cache object for instance.
‣ Nowadays, most modern PHP frameworks heavily use Dependency
Injection to provide a set of decoupled but cohesive components
2
PHP DEPENDENCY INJECTION
CONSTRUCTOR, SETTER & PROPERTY INJECTION
<?php
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
// ...
}
class User
{
function setSessionStorage($storage)
{
$this->storage = $storage;
}
// ...
}
class User
{
public $sessionStorage;
}
$user->sessionStorage = $storage;
3
PHP DEPENDENCY INJECTION
EXAMPLE OF USAGE
<?php
// symfony: A constructor injection example
$dispatcher = new sfEventDispatcher();
$storage = new sfMySQLSessionStorage(array('database' => 'session', 'db_table' => 'session'));
$user = new sfUser($dispatcher, $storage, array('default_culture' => 'en'));
// Zend Framework: A setter injection example
$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);
4
PHPUNIT
EXAMPLE CLASS WITHOUT & WITH DI
<?php
class StoreService
{
public function getStoreCoordinates($store) {
$geolocationService = new GoogleMaps();
// or $geolocationService =
GoogleMaps::getInstance() if you use singletons
return $geolocationService-
>getCoordinatesFromAddress($store->getAddress());
}
}
5
class StoreService {
private $geolocationService;
public function __construct(GeolocationService
$geolocationService) {
$this->geolocationService = $geolocationService;
}
public function getStoreCoordinates($store) {
return $this->geolocationService-
>getCoordinatesFromAddress($store->getAddress());
}
}
interface GeolocationService {
public function getCoordinatesFromAddress($address);
}
class GoogleMaps implements GeolocationService { ... }
class OpenStreetMap implements GeolocationService { ... }
// The StoreService is no longer tightly coupled to its dependency.
PHP DEPENDENCY INJECTION
BEST PRACTICES
‣ Here are some basic rules to follow:
‣ never get an entry from the container directly (always use dependency
injection)
‣ more generally, write code decoupled from the container
‣ type-hint against interfaces, configure which implementation to use in the
container's configuration
‣ Writing controllers - inject dependencies in properties
‣ Writing services - start using constructor injection and autowiring
‣ Using libraries - define dependencies in your configuration file. It is
recommended using an anonymous function when the configuration gets a bit
complex (anonymous function allows you to write real PHP code).
6
PHP DEPENDENCY INJECTION
PHP DI RESOURCES
‣ PHP DI
‣ http://php-di.org/doc/getting-started.html
‣ What is dependency injection?
‣ http://fabien.potencier.org/what-is-dependency-injection.html
‣ Dependency Injection in PHP
‣ https://code.tutsplus.com/tutorials/dependency-injection-in-php--
net-28146
7

14 Dependency Injection #burningkeyboards

  • 1.
  • 2.
    PHP DEPENDENCY INJECTION INTRO ‣Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields ‣ As a rule of thumb, constructor injection is best for required dependencies, like in our example, and setter injection is best for optional dependencies, like a cache object for instance. ‣ Nowadays, most modern PHP frameworks heavily use Dependency Injection to provide a set of decoupled but cohesive components 2
  • 3.
    PHP DEPENDENCY INJECTION CONSTRUCTOR,SETTER & PROPERTY INJECTION <?php class User { function __construct($storage) { $this->storage = $storage; } // ... } class User { function setSessionStorage($storage) { $this->storage = $storage; } // ... } class User { public $sessionStorage; } $user->sessionStorage = $storage; 3
  • 4.
    PHP DEPENDENCY INJECTION EXAMPLEOF USAGE <?php // symfony: A constructor injection example $dispatcher = new sfEventDispatcher(); $storage = new sfMySQLSessionStorage(array('database' => 'session', 'db_table' => 'session')); $user = new sfUser($dispatcher, $storage, array('default_culture' => 'en')); // Zend Framework: A setter injection example $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); 4
  • 5.
    PHPUNIT EXAMPLE CLASS WITHOUT& WITH DI <?php class StoreService { public function getStoreCoordinates($store) { $geolocationService = new GoogleMaps(); // or $geolocationService = GoogleMaps::getInstance() if you use singletons return $geolocationService- >getCoordinatesFromAddress($store->getAddress()); } } 5 class StoreService { private $geolocationService; public function __construct(GeolocationService $geolocationService) { $this->geolocationService = $geolocationService; } public function getStoreCoordinates($store) { return $this->geolocationService- >getCoordinatesFromAddress($store->getAddress()); } } interface GeolocationService { public function getCoordinatesFromAddress($address); } class GoogleMaps implements GeolocationService { ... } class OpenStreetMap implements GeolocationService { ... } // The StoreService is no longer tightly coupled to its dependency.
  • 6.
    PHP DEPENDENCY INJECTION BESTPRACTICES ‣ Here are some basic rules to follow: ‣ never get an entry from the container directly (always use dependency injection) ‣ more generally, write code decoupled from the container ‣ type-hint against interfaces, configure which implementation to use in the container's configuration ‣ Writing controllers - inject dependencies in properties ‣ Writing services - start using constructor injection and autowiring ‣ Using libraries - define dependencies in your configuration file. It is recommended using an anonymous function when the configuration gets a bit complex (anonymous function allows you to write real PHP code). 6
  • 7.
    PHP DEPENDENCY INJECTION PHPDI RESOURCES ‣ PHP DI ‣ http://php-di.org/doc/getting-started.html ‣ What is dependency injection? ‣ http://fabien.potencier.org/what-is-dependency-injection.html ‣ Dependency Injection in PHP ‣ https://code.tutsplus.com/tutorials/dependency-injection-in-php-- net-28146 7