Dependency Injection in PHP
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Dependency Injection in PHP

  • 10,605 views
Uploaded on

Slides from my talk during PHPCon Poland. ...

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
10,605
On Slideshare
8,436
From Embeds
2,169
Number of Embeds
23

Actions

Shares
Downloads
68
Comments
3
Likes
18

Embeds 2,169

http://localhost 773
http://xlab.pl 516
https://twitter.com 319
http://techportal.inviqa.com 300
http://www.webtuts.com.pl 107
http://piotrpasich.com 63
http://piotrpasich.papidev.com 34
http://cloud.feedly.com 22
http://www.google.com 6
http://digg.com 6
http://symfony2developer.com 3
http://192.168.1.5 3
http://feedly.com 2
http://www.linkedin.com 2
http://ipv6.symfony2developer.com 2
http://xsolve_feed.tutorials 2
http://rss-reader.debian 2
http://www.planet-php.net 2
http://newsblur.com 1
http://feeds.feedburner.com 1
http://test.idoc.vn 1
https://drive.jolicloud.com 1
http://192.168.0.100 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

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