Your SlideShare is downloading. ×
0
Dependency
Injection in PHP

PHPCon Poland
Szczyrk 25/10/13

!

by @cakper
flickr.com/limowreck666/223731385/
Kacper Gunia // @cakper
Software Engineer @SensioLabsUK
Symfony Certified Developer
#Symfony-PL // SymfonyLab.pl
Silesian P...
Inversion of Control
Dependency Injection
Events
Aspect Oriented
Programming
flickr.com/goetter/4559773791/
Diving into
Dependency Injection

flickr.com/haniamir/651043585/
Dependency Injection
!
!

class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  public	
  function	
  playDisc(Disc	
  $disc)	
  
	...
Dependency Injection
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
  $tv;	
  
!

	
  	
  	
  	
  public	
  functio...
Dependency Injection
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
  $tv;	
  
!

	
  	
  	
  	
  public	
  functio...
Dependency Injection
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
  $device;	
  
!

	
  	
  	
  	
  public	
  fun...
Nailed it!
“Dependency Injection 

is where components are given
their dependencies through
their constructors, methods, or
directly ...
Types of Injection
Constructor
Setter
Property
Reflection
flickr.com/jensfinke/4417602702/
Constructor Injection
class	
  Tv	
  implements	
  HdmiDevice{}	
  
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
...
Setter Injection
class	
  BlurayDisc	
  implements	
  Disc{}	
  
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
  $...
Property Injection
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  public	
  $remote;	
  
}	
  
!

$dvdPlayer	
  =	
  new	
  ...
Reflection Injection
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
  $powerSupply;	
  
}	
  
!

$dvdPlayer	
  =	
  ...
Pros & Cons

flickr.com/paperpariah/3589690234/
Advantage #1

Decoupling

flickr.com/roonster/3387705446/
Advantage #2

Dependency
Inversion Principle

flickr.com/antonsiniorg/1876733029/
Advantage #3

Reusability

flickr.com/ejpphoto/2314610838/
Advantage #4

Clean code

flickr.com/38659937@N06/4020413080/
Advantage #5

Easier testing

flickr.com/nattu/895220635/
Advantage #6

Instance
management

flickr.com/34094515@N00/3817086937/
Advantage #7

IDE support

flickr.com/gavin_fordham/9407339641/
Disadvantage

Complex
initialisation

flickr.com/toniblay/52445415/
Simple Solution

Factory

flickr.com/lenscrack/5577431429/
Proper Solution

Dependency Injection
Container

flickr.com/thomashawk/24089964/
“Dependency Injection
Container is simply a PHP
object that manages the
instantiation of other objects”
!

We call them “S...
Our DvdPlayer
!
!

$tv	
  =	
  new	
  Tv('Samsung	
  40"');	
  
$dvdPlayer	
  =	
  new	
  DvdPlayer($tv);	
  
!

$disc	
  ...
Simple Container class
class	
  Container	
  
{	
  
	
  	
  	
  	
  public	
  function	
  getTv()	
  
	
  	
  	
  	
  {	
 ...
Container use
!
!

$container	
  =	
  new	
  Container();	
  
!

$dvdPlayer	
  =	
  $container-­‐>getDvdPlayer();	
  
!

$...
DIC Implementations
Twittee

Pimple

PHP-DI 

ZendDi

IlluminateContainer

OrnoDi

LeagueDi

SymfonyDependencyInjection 
fl...
DI & DIC Patterns

flickr.com/thelearningcurvedotca/8645721482/
Pattern #1

Expect Interfaces,
not Implementations

flickr.com/deapeajay/2969264395/
Pattern #2

Don’t check null values

flickr.com/g-ratphotos/3328593629/
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  public	
  $disc;	
  
!

	
  	
  	
  	
  public	
  function	
  play()	
  
	
  ...
Pattern #3

Avoid ‘Service Locator’

flickr.com/mateus27_24-25/2224073271/
class	
  DvdPlayer	
  
{	
  
	
  	
  	
  	
  private	
  $locator;	
  
!

	
  	
  	
  	
  public	
  function	
  __construct...
Pattern #4

Don’t inject whole
container

flickr.com/ucumari/580865728/
Pattern #5

In DIC store
Services and Properties,
but not Entities

flickr.com/madlyinlovewithlife/8674850717/
Pattern #6

Don’t be afraid to create
plenty of small Classes

flickr.com/geoki/2691420977/
Symfony DIC
in action
Services
new	
  Tv('Samsung	
  40”’)	
  
!

services:	
  
	
  	
  tv:	
  
	
  	
  	
  	
  class:	
  	
  	
  	
  	
  	
  Tv...
Parameters
new	
  Tv('Samsung	
  40”’)	
  
!

parameters:	
  
	
  	
  tv_name:	
  	
  Samsung	
  40"	
  
Parameters & Services
new	
  Tv('Samsung	
  40”’)	
  
!

parameters:	
  
	
  	
  tv_name:	
  	
  Samsung	
  40"	
  
!

ser...
Compiled Container
!
!
!
!

protected	
  function	
  getTvService()	
  
{	
  
	
  	
  	
  	
  return	
  $this-­‐>services[...
Static Factory
services:	
  
	
  	
  	
  	
  tv	
  
	
  	
  	
  	
  	
  	
  	
  	
  class:	
  	
  	
  	
  	
  	
  	
  	
  ...
Factory
services:	
  
	
  	
  	
  	
  tv_factory:	
  
	
  	
  	
  	
  	
  	
  	
  	
  class:	
  	
  	
  	
  	
  	
  	
  	
...
Optional Dependencies
class	
  DvdPlayer	
  
{	
  
	
  	
  function	
  __construct(HdmiDevice	
  $device	
  =	
  null){}	
...
Lazy-loaded Services
services:	
  
	
  	
  tv:	
  
	
  	
  	
  	
  class:	
  	
  	
  	
  	
  	
  Tv	
  
	
  	
  	
  	
  ar...
Private Services
services:	
  
	
  	
  drm_decryptor:	
  
	
  	
  	
  	
  class:	
  	
  	
  	
  	
  	
  DrmDecryptor	
  
	...
Scopes
services:	
  
	
  	
  tv:	
  
	
  	
  	
  	
  class:	
  	
  	
  	
  	
  	
  Tv	
  
	
  	
  	
  	
  arguments:	
  	
...
PHPStorm
support
Adrien Brault

sxc.hu/photo/228094/
Questions?
!

Thank you! :)
!

joind.in/9760
flickr.com/eole/3809742516/
Upcoming SlideShare
Loading in...5
×

Dependency Injection in PHP

11,022

Published on

Slides from my talk during PHPCon Poland.
Szczyrk 25/10/2013

3 Comments
19 Likes
Statistics
Notes
No Downloads
Views
Total Views
11,022
On Slideshare
0
From Embeds
0
Number of Embeds
26
Actions
Shares
0
Downloads
99
Comments
3
Likes
19
Embeds 0
No embeds

No notes for slide

Transcript of "Dependency Injection in PHP"

  1. 1. Dependency Injection in PHP PHPCon Poland Szczyrk 25/10/13 ! by @cakper flickr.com/limowreck666/223731385/
  2. 2. Kacper Gunia // @cakper Software Engineer @SensioLabsUK Symfony Certified Developer #Symfony-PL // SymfonyLab.pl Silesian PHP User Group // SPUG.pl
  3. 3. Inversion of Control Dependency Injection Events Aspect Oriented Programming flickr.com/goetter/4559773791/
  4. 4. Diving into Dependency Injection flickr.com/haniamir/651043585/
  5. 5. Dependency Injection ! ! class  DvdPlayer   {          public  function  playDisc(Disc  $disc)          {                  echo  'Now  playing:  '.$disc-­‐>getMovieTitle();   !                $tv  =  new  Tv('Samsung  40"');                  $tv-­‐>sendToOutput($disc-­‐>getResource());          }   }
  6. 6. Dependency Injection class  DvdPlayer   {          private  $tv;   !        public  function  __construct()          {                  $this-­‐>tv  =  new  Tv('Samsung  40"');;          }   !        public  function  playDisc(Disc  $disc)          {                  echo  'Now  playing:  '  .  $disc-­‐>getMovieTitle();                  $this-­‐>tv-­‐>sendToOutput($disc-­‐>getResource());          }   }
  7. 7. Dependency Injection class  DvdPlayer   {          private  $tv;   !        public  function  __construct(Tv  $tv)          {                  $this-­‐>tv  =  $tv;          }  //  (...)   }   ! $tv  =  new  Tv('Samsung  40"');   $dvdPlayer  =  new  DvdPlayer($tv);
  8. 8. Dependency Injection class  DvdPlayer   {          private  $device;   !        public  function  __construct(HdmiDevice  $device)          {                  $this-­‐>device  =  $device;          }  //  (...)   }   ! $projector  =  new  Projector('Epson  EB');   $dvdPlayer  =  new  DvdPlayer($tv);
  9. 9. Nailed it!
  10. 10. “Dependency Injection 
 is where components are given their dependencies through their constructors, methods, or directly into fields.” ! “(...) it is a 25-dollar term for a 5-cent concept” source: picocontainer.codehaus.org jamesshore.com
  11. 11. Types of Injection Constructor Setter Property Reflection flickr.com/jensfinke/4417602702/
  12. 12. Constructor Injection class  Tv  implements  HdmiDevice{}   class  DvdPlayer   {          private  $device;   !        public  function  __construct(HdmiDevice  $device)          {                  $this-­‐>device  =  $device;          }   }   ! $tv  =  new  Tv('Samsung  40"');   $dvdPlayer  =  new  DvdPlayer($tv);
  13. 13. Setter Injection class  BlurayDisc  implements  Disc{}   class  DvdPlayer   {          private  $disc;   !        public  function  setDisc(Disc  $disc)          {                  $this-­‐>disc  =  $disc;          }   }   ! $disc  =  new  BlurayDisc('Pulp  Fiction');   $dvdPlayer  =  new  DvdPlayer();   $dvdPlayer-­‐>setDisc($disc);
  14. 14. Property Injection class  DvdPlayer   {          public  $remote;   }   ! $dvdPlayer  =  new  DvdPlayer();   $dvdPlayer-­‐>remote  =  new  Remote();
  15. 15. Reflection Injection class  DvdPlayer   {          private  $powerSupply;   }   ! $dvdPlayer  =  new  DvdPlayer();   $reflector  =  new  ReflectionClass($dvdPlayer);   $powerSupply  =  $reflector-­‐>getProperty('powerSupply');   $powerSupply-­‐>setAccessible(true);   ! $powerSupply-­‐>setValue($dvdPlayer,  new  PowerSupply());
  16. 16. Pros & Cons flickr.com/paperpariah/3589690234/
  17. 17. Advantage #1 Decoupling flickr.com/roonster/3387705446/
  18. 18. Advantage #2 Dependency Inversion Principle flickr.com/antonsiniorg/1876733029/
  19. 19. Advantage #3 Reusability flickr.com/ejpphoto/2314610838/
  20. 20. Advantage #4 Clean code flickr.com/38659937@N06/4020413080/
  21. 21. Advantage #5 Easier testing flickr.com/nattu/895220635/
  22. 22. Advantage #6 Instance management flickr.com/34094515@N00/3817086937/
  23. 23. Advantage #7 IDE support flickr.com/gavin_fordham/9407339641/
  24. 24. Disadvantage Complex initialisation flickr.com/toniblay/52445415/
  25. 25. Simple Solution Factory flickr.com/lenscrack/5577431429/
  26. 26. Proper Solution Dependency Injection Container flickr.com/thomashawk/24089964/
  27. 27. “Dependency Injection Container is simply a PHP object that manages the instantiation of other objects” ! We call them “Services” source: symfony.com
  28. 28. Our DvdPlayer ! ! $tv  =  new  Tv('Samsung  40"');   $dvdPlayer  =  new  DvdPlayer($tv);   ! $disc  =  new  Disc('Pulp  Fiction');   $dvdPlayer-­‐>playDisc($disc);
  29. 29. Simple Container class class  Container   {          public  function  getTv()          {                  return  new  Tv('Samsung  40"');          }   !        public  function  getDvdPlayer()          {                  return  new  DvdPlayer($this-­‐>getTv());          }   }
  30. 30. Container use ! ! $container  =  new  Container();   ! $dvdPlayer  =  $container-­‐>getDvdPlayer();   ! $disc  =  new  Disc('Pulp  Fiction');   $dvdPlayer-­‐>playDisc($disc);
  31. 31. DIC Implementations Twittee Pimple PHP-DI  ZendDi IlluminateContainer OrnoDi LeagueDi SymfonyDependencyInjection  flickr.com/smb_flickr/313116995/
  32. 32. DI & DIC Patterns flickr.com/thelearningcurvedotca/8645721482/
  33. 33. Pattern #1 Expect Interfaces, not Implementations flickr.com/deapeajay/2969264395/
  34. 34. Pattern #2 Don’t check null values flickr.com/g-ratphotos/3328593629/
  35. 35. class  DvdPlayer   {          public  $disc;   !        public  function  play()          {                  if  (!is_null($this-­‐>disc))  {                          $this-­‐>sendToOutput($this-­‐>disc-­‐>getResource());                  }          }   !        public  function  play()          {                  if  ($this-­‐>disc  instanceof  Disc)  {                          $this-­‐>sendToOutput($this-­‐>disc-­‐>getResource());                  }          }   }
  36. 36. Pattern #3 Avoid ‘Service Locator’ flickr.com/mateus27_24-25/2224073271/
  37. 37. class  DvdPlayer   {          private  $locator;   !        public  function  __construct()          {                  $this-­‐>locator  =  ServiceLocator::getInstance();          }   ! !        public  function  playDisc(Disc  $disc)          {                  $this-­‐>locator                            -­‐>getTv()                            -­‐>sendToOutput($disc-­‐>getResource());          }   }
  38. 38. Pattern #4 Don’t inject whole container flickr.com/ucumari/580865728/
  39. 39. Pattern #5 In DIC store Services and Properties, but not Entities flickr.com/madlyinlovewithlife/8674850717/
  40. 40. Pattern #6 Don’t be afraid to create plenty of small Classes flickr.com/geoki/2691420977/
  41. 41. Symfony DIC in action
  42. 42. Services new  Tv('Samsung  40”’)   ! services:      tv:          class:            Tv          arguments:    [“Samsung  40"”]  
  43. 43. Parameters new  Tv('Samsung  40”’)   ! parameters:      tv_name:    Samsung  40"  
  44. 44. Parameters & Services new  Tv('Samsung  40”’)   ! parameters:      tv_name:    Samsung  40"   ! services:      tv:          class:            Tv          arguments:    [“%tv_name%”]   ! $container-­‐>get('tv');
  45. 45. Compiled Container ! ! ! ! protected  function  getTvService()   {          return  $this-­‐>services['tv']  =  new  Tv('Samsung');   }  
  46. 46. Static Factory services:          tv                  class:                    Tv                    factory_class:    TvFactory                  factory_method:  get
  47. 47. Factory services:          tv_factory:                  class:                      TvFactory          tv                  class:                      Tv                    factory_service:  tv_factory                  factory_method:    get
  48. 48. Optional Dependencies class  DvdPlayer   {      function  __construct(HdmiDevice  $device  =  null){}   }   ! services:      tv:          class:            Tv          arguments:    [%tv_name%]      dvd_player:              class:        DvdPlayer              arguments  ["@?tv"]  
  49. 49. Lazy-loaded Services services:      tv:          class:            Tv          arguments:    [“%tv_name%”]       lazy:         true
  50. 50. Private Services services:      drm_decryptor:          class:            DrmDecryptor       public:       false      dvd_player:              class:        DvdPlayer              arguments  [“@drm_decryptor”]
  51. 51. Scopes services:      tv:          class:            Tv          arguments:    [“%tv_name%”]       scope:       prototype
  52. 52. PHPStorm support Adrien Brault sxc.hu/photo/228094/
  53. 53. Questions? ! Thank you! :) ! joind.in/9760 flickr.com/eole/3809742516/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×