Dependency Injection in PHP
- 2. Kacper Gunia // @cakper
Software Engineer @SensioLabsUK
Symfony Certified Developer
#Symfony-PL // SymfonyLab.pl
Silesian PHP User Group // SPUG.pl
- 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);
- 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
- 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);
- 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());
- 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);
- 32. DI & DIC Patterns
flickr.com/thelearningcurvedotca/8645721482/
- 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());
}
}
}
- 37. class
DvdPlayer
{
private
$locator;
!
public
function
__construct()
{
$this-‐>locator
=
ServiceLocator::getInstance();
}
!
!
public
function
playDisc(Disc
$disc)
{
$this-‐>locator
-‐>getTv()
-‐>sendToOutput($disc-‐>getResource());
}
}
- 39. Pattern #5
In DIC store
Services and Properties,
but not Entities
flickr.com/madlyinlovewithlife/8674850717/
- 44. Parameters & Services
new
Tv('Samsung
40”’)
!
parameters:
tv_name:
Samsung
40"
!
services:
tv:
class:
Tv
arguments:
[“%tv_name%”]
!
$container-‐>get('tv');
- 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"]
- 50. Private Services
services:
drm_decryptor:
class:
DrmDecryptor
public:
false
dvd_player:
class:
DvdPlayer
arguments
[“@drm_decryptor”]