4. WHY USE COMPONENTS
Solve common web application problems
Incredibly well documented
(relatively) Standalone: use them how you like
Ideal for refactoring
5. INSTALLATION
Composer: the knight in shining armour
Download it
cr - hts/gtopsrogisalr|pp
ul s tp:/ecmoe.r/ntle h
Create a composer.json file
{
"eur" {
rqie:
"yfn/h-rjc-ae:"e-atr,
smoytepoetnm" dvmse"
}
}
Run composer
ppcmoe.hrisal
h opsrpa ntl
7. WHAT'S IN STORE
Autoloading classes with ClassLoader
Routing requests with Routing
Listening for events with the EventDispatcher
Parsing YAML files with the YAML component
HTTP Requests and responses with HTTPFoundation
Injecting dependencies with Pimple
Templates with Twig
16. PIMPLE
Pimple is a dependency injection container which lets us
easily manage and inject our dependencies into our projects.
We put the dependencies into a container, and then we inject
this container into our code which uses it.
17. REFACTORING TO USE A CONTAINER
<pp
?h
casSmMdl
ls oeoe
{
pbi fnto _cntut)
ulc ucin _osrc(
{
$q =";
sl "
$ur =Dtbs:qey$q)
qey aaae:ur(sl;
}
}
bfr
eoe
<pp
?h
casSmMdl
ls oeoe
{
pbi fnto _cntut$otie=ra()
ulc ucin _osrc(cnanrary)
{
/ TD:frhrrfco oc dic i pae
/ OO ute eatr ne ... n lc
$q =";
sl "
$ur =Dtbs:qey$q)
qey aaae:ur(sl;
}
}
atr
fe
18. LAZY LOADING
By utilising closures, code isn't run until it is first requested /
called; i.e. database connection is established only when you
first try and use the connection
$otie[d' =fnto(c {
cnanr'b] ucin$)
rtr nwD(..,$[d_sr] $[d_w')
eun e PO"." c'bue', c'bpd];
};
20. FURTHER REFACTORING
<pp
?h
casSmMdl
ls oeoe
{
pbi fnto _cntut$otie=ra()
ulc ucin _osrc(cnanrary)
{
$q =";
sl "
$ur =$otie[d'-qey$q)
qey cnanr'b]>ur(sl;
}
}
21. CREATING YOUR OWN CONTAINER
Particularly useful for re-use and different use-cases (cli vs
web)
<pp
?h
nmsaePoetFaeokCnanr
aepc rjcrmwrotie;
casMCnanretnsipe
ls yotie xed Pml
{
pbi fnto _cntutary$aus=ary)
ulc ucin _osrc(ra vle ra()
{
prn:_cntut$aus;
aet:_osrc(vle)
/ adtig t tecnanrhr
/ d hns o h otie ee
}
}
22. CONTROLLER REFACTORING (BEFORE)
<pp
?h
casSmCnrle
ls oeotolr
{
/ ..
/ .
pbi fnto smAto(
ulc ucin oecin)
{
$oe =nwSmMdl$hs>otie)
mdl e oeoe(ti-cnanr;
}
}
23. REDUCING NEW...CONTAINERS WITHIN
CONTAINERS
<pp
?h
nmsaeFciiFaeokCnanr
aepc aefrmwrotie;
casDtAcsOjcsetnsipe
ls aacesbet xed Pml
{
pbi fnto _cntutary$aus=ary)
ulc ucin _osrc(ra vle ra()
{
prn:_cntut$aus;
aet:_osrc(vle)
$hs'sr]=$hs>hr(ucin$){
ti[ue' ti-saefnto(c
rtr nwUeDo$[cnanr];
eun e sra(c'otie')
};
)
}
}
27. A YAML FILE
d_yq:
bmsl
hs:'oahs'
ot lclot
ue:'ot
sr ro'
ps:'
as '
nm:'b
ae d'
pr:30
ot 36
at_ac:tu
uopth re
gnrl
eea:
pouto:fle
rdcin as
si:'ees'
kn rlae
st_r:'tp/lclot46/
ieul ht:/oahs:57'
28. PARSING A YAML FILE
$al=nwSmoyCmoetYmasr)
ym e yfnopnnalPre(;
$asdstig =$al>as(iegtcnet(_I_./ofgyl)
pre_etns ym-prefl_e_otns_DR_'cni.m')
;
32. REFACTORING FOUNDATIONS
Mostly taken care of when we ensured all controllers were
objects and that the new structure followed PSR-0.
Controllers refactored like so:
pbi fnto _cntut$otie)
ulc ucin _osrc(cnanr
{
$hs>otie =$otie;
ti-cnanr cnanr
}
pbi fnto aOdcin$ae $oei)
ulc ucin nlAto(dt, sm_d
pbi fnto aeAto(ulprm=ra()
ulc ucin Nwcin$r_aasary)
33. SETTING IT UP
Alias some of the namespaces
ueSmoyCmoetCniieoao;
s yfnopnnofgFlLctr
ueSmoyCmoetRuigRqetotx;
s yfnopnnotneusCnet
ueSmoyCmoetRuig
s yfnopnnotn;
Prepare dependencies
$oao =nwFlLctraryFAEOKPT);
lctr e ieoao(ra(RMWR_AH)
$eus =(se(_EVR'EUS_R')?$SRE[RQETUI]';
rqet ist$SRE[RQETUI]) _EVR'EUS_R':'
$otx =nwRqetotx(rqet $SRE[RQETMTO')
cnet e eusCnet$eus, _EVR'EUS_EHD];
Construct
$otr=nwRuigRue(e YmFlLae(lctr,'otsyl,
rue e otnotrnw alieodr$oao) rue.m'
ary) $otx)
ra(, cnet;
35. ROUTING
ty{
r
$r =(se(_EVR'EUS_R') ?$SRE[RQETUI]:'
ul ist$SRE[RQETUI]) _EVR'EUS_R'
';
/ gtrdo tetaln sah
/ e i f h riig ls
$r =(tln$eusUL >1 ?rrm$eusUL '' :$r;
ul sre(rqetR) ) ti(rqetR, /) ul
$ot =$otr>ac(ul;
rue rue-mth$r)
$otolr=nw$ot[cas]$otie)
cnrle e rue'ls'(cnanr;
$cin=$otolr>rue'ehd])
ato cnrle-$ot[mto'(;
}
cth(otnxetoeoreoFudxeto $){
ac RuigEcpinRsucNtonEcpin e
/ td:44
/ oo 0
}
36. ROUTE VARIABLES
cmetsoyad
omn_tr_d:
pten /es{aeoy/dt}{ril}
atr: nw/ctgr}{ae/atce
dfut:{cas 'omnsCnrle:adomn'}
eals ls: Cmetotolr:dCmet
rqieet:
eurmns
dt:"09{}[-]2-09{}
ae [-]2-09{}[-]4"
_ehd PS
mto: OT
$ot =$otr>ac(ul;
rue rue-mth$r)
$otolr=nw$ot[cas]$otie)
cnrle e rue'ls'(cnanr;
$aibe =$ot;
vrals rue
ust$aibe[nm',$aibe[cas] $aibe[mto')
ne(vrals'ae] vrals'ls', vrals'ehd];
$cin=$otolr>rue'ehd])
ato cnrle-$ot[mto'(;
37. AUTHENTICATION CONTROL
acut
con:
pten /con
atr: acut
dfut:{cas 'rjcconotolr,mto:'aae,lg
eals ls: PoetAcutCnrle' ehd mng' og
e_n tu }
di: re
rqieet:
eurmns
_ehd GT
mto: E
i (se(rue'ogdi') {
f ist$ot[lge_n])
i (snl(cnanr'sr]){
f i_ul$otie[ue')
/ Ue i tyn t acs lge i ol cnet-rdrc t
/ sr s rig o ces ogd n ny otn eiet o
lgnadsoerdrc
oi n tr eiet
$SSIN'eiet]=$SRE[RQETUI]
_ESO[rdrc' _EVR'EUS_R';
$vn =nwEeteusRdrcin$otie[stig'[b
eet e vnsRqeteieto(cnanr'etns]'a
s_r' .'oi/)
eul] lgn';
$hs>otie[dsace'-dsac(rdrc' $vn)
ti-cnanr'ipthr]>ipth'eiet, eet;
}
}
43. USE CASES
Redirecting the user / flash notifications
Sending transactional emails
Adding a product to a basket
Hooking into other features to share other features e.g.
tweet on content creation
44. REDIRECTION & "FLASH" NOTIFICATIONS
1. Raise an event
2. Listen for notification events, and log the notification in-
session
3. Listen for a redirect event, and redirect
Ordering is important here as we don't want to redirect
before setting the session!
50. LISTEN UP...
Create an event dispatcher
Create instance of listener
Add the listener
Event name
A callable e.g. Object/Method array combo, Closure, etc
Priority: for multiple listeners listening for the same
event
51. LISTEN UP
$ipthr=nwEetipthr)
dsace e vnDsace(;
/ Ntfcto (ucs,Wrig Err
/ oiiain Sces ann, ro)
$ePritnNtfcto =nwLseesStessatoiiain)
stessatoiiain e itnrePritnNtfcto(;
$ipthr>dLsee(ntf' ary$ePritnNtfcto,'e
dsace-aditnr'oiy, ra(stessatoiiain st
Ntfcto',1)
oiiain) 0;
/ Rdrc
/ eiet
$eietsr=nwLseesRdrc(;
rdrcUe e itnreiet)
$ipthr>dLsee(ntfy,ary$eietsr 'eietsr)
dsace-aditnr'oii' ra(rdrcUe, rdrcUe',
0;
)
52. DISPATCH
$r =$aeul.'con'
ul bs_r acut;
$esg ='orpswr wscagdscesuy'
msae Yu asod a hne ucsfl.;
$vn =nwEeteietbeoiiain$r,$esg,'ucs';
eet e vnsRdrcalNtfcto(ul msae sces)
$ipthr>ipth'oiy,$vn)
dsace-dsac(ntf' eet;
54. STANDARD EVENT
We tend to use our own event object which extends the
symfony one. This holds a payload which is our event related
object.
<pp
?h
nmsaePoetFaeokEet;
aepc rjcrmwrvns
casEetetnsyfnopnnvnDsacevn
ls vn xed SmoyCmoetEetipthrEet
{
poetd$aLa;
rtce pyod
pbi fnto staLa(pyod
ulc ucin ePyod$ala)
{
$hs>aLa =$ala;
ti-pyod pyod
}
pbi fnto gtaLa(
ulc ucin ePyod)
{
rtr $hs>aLa;
eun ti-pyod
}
}
55. QUEUEABLE
Interface to define an event as something that can be
queued
Listener to queue the event e.g. in beanstalk
<pp
?h
nmsaePoetFaeokEet;
aepc rjcrmwrvns
itraeQeebenefc
nefc uualItrae
{
pbi fnto gtd)
ulc ucin eI(;
}
56. QUEUE AN EVENT IN YOUR LISTENER
pbi fnto cekvn(vnsEet$vn)
ulc ucin hcEetEetvn eet
{
i (eet>ePyod)isaco Qeebenefc){
f $vn-gtaLa( ntnef uualItrae
$ue_a =ary'e.sr = 'we';
tbsmp ra(nwue' > tet)
$d=$vn-gtaLa(-gtd)
i eet>ePyod)>eI(;
$ue=$ue_a[eet>eNm(]
tb tbsmp$vn-gtae);
$hs>otie[q]>sTb(tb)>u(i)
ti-cnanr''-ueue$ue-pt$d)
}
}
59. SETUP AND LOAD
/ cet ati flsse lae s i cnacs tmlts
/ rae wg ieytm odr o t a ces epae
$odr=nwwgLae_ieytm'epae';
lae e Ti_odrFlsse(tmlts)
/ cet anwti evrnetadps i telae
/ rae e wg niomn n as t h odr
$wg=wgEvrnet$odr;
ti Ti_niomn(lae)
Load and render template
/ la tetmlt
/ od h epae
$wg>odepae'ne.wg)
ti-laTmlt(idxti';
/ rne i
/ edr t
$wg>edrary'il'= 'aibe);
ti-rne(ra(tte > vral')
60. REFACTORING TO TWIG
A place to prepare twig and also perform any non-twig
presentation logic. Keeps the data de-coupled from the
workings of the template engine
asrc casVe
btat ls iw
{
pbi fnto _cntut$otie)
ulc ucin _osrc(cnanr
{
$odr=nwwgLae_ieytm'epae';
lae e Ti_odrFlSse(tmlts)
$hs>epaenie=nwwgEvrnet$odr;
ti-tmltEgn e Ti_niomn(lae)
}
pbi fnto gnrt(mdlnl)
ulc ucin eeae$oe=ul;
pbi fnto rne(tmlt_ie
ulc ucin edr$epaefl)
{
$hs>epaenie>odepae$epaefl)
ti-tmltEgn-laTmlt(tmlt_ie;
eh $wg>edr$hs>otie-tmltVrals;
co ti-rne(ti-cnanr>epaeaibe)
ei;
xt
}
}
65. SETUP OUTPUT CACHING
ueDsrol2CceCce
s earlaahah;
ueDsrol2CceAatrFl;
s earlaahdpeie
$dpe =nwFl(;
aatr e ie)
$dpe-stpin't' (n)$otie[ms_ofg]>ah-tl;
aatr>eOto(tl, it cnanr'iccni'-cce>t)
ty{
r
$dpe-stpin'ahDr,'vrwwccepgs';
aatr>eOto(ccei' /a/w/ah/ae/)
}
cth(Ecpin$){
ac xeto e
/ tmoaiyltteapiainuete/m fle?
/ eprrl e h plcto s h tp odr
}
$ah =nwCce$dpe)
cce e ah(aatr;
66. INTEGRATING OUTPUT CACHING
$ah_e =m5$r)
cceky d(ul;
i (cceeald& $ot[ccal'){
f $ah_nbe & rue'ahbe]
i(snl(ti-cnanr'sr]& $ah-hs$ah_e) {
fi_ul$hs>otie[ue' & cce>a(cceky)
eh $ah-gt$ah_e)
co cce>e(cceky;
ei;
xt
}
}
67. VALIDATOR (FUEL)
There is a symfony component which does this, though we
opted for the Fuel validation component.
69. REQUEST
ueSmoyCmoetHtFudtoeus;
s yfnopnntponainRqet
$eus =Rqet:raermlbl(;
rqet eus:cetFoGoas)
Provides a parameter bag of properties
Property Purpose
request store $_POST
query store $_GET
cookies store $_COOKIE
attributes application specific
files $_FILE
server $_SERVER
headers subset of $_SERVER
70. A PARAMETER BAG?
Request properties are all ParameterBag or sub-classes
Provides special methods to manage contents, including:
all
keys
get
add
set
has
remove
71. RESPONSE
ueSmoyCmoetHtFudtoepne
s yfnopnntponainRsos;
$epne=nwRsos(;
rsos e epne)
$epne>eCnet'el PPK)
rsos-stotn(Hlo HU';
$epne>eSauCd(0)
rsos-stttsoe20;
$epne>edr-st'otn-ye,'etpan)
rsos-haes>e(CnetTp' tx/li';
/ atraiey.
/ lentvl..
$epne=nwRsos(HloPPK,20 ary'otn-ye,'et
rsos e epne'el HU' 0, ra(cnettp' tx/
pan);
li')
$epne>rpr(;
rsos-peae)
/ sn tersos t teue
/ ed h epne o h sr
$epne>ed)
rsos-sn(;