SlideShare uma empresa Scribd logo
1 de 78
Baixar para ler offline
REFACTORING TO
SYMFONY COMPONENTS
     ...AND THEIR FRIENDS
         Michael Peacock
@MICHAELPEACOCK
Head Developer @ Ground Six
Technical author
Occasional conference speaker
THE COMPONENTS
http://symfony.com/components
WHY USE COMPONENTS
Solve common web application problems
Incredibly well documented
(relatively) Standalone: use them how you like
Ideal for refactoring
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
THEIR FRIENDS
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
OUR REFACTORING TALE
SPEED UP DEVELOPMENT & MODERNISE LEGACY CODEBASE
OUR JOURNEY
Messy structure, some procedural code: ClassLoader
Globals, singletons and crazy objects: Pimple
Scattered routing logic, long if/else conditions: Routing
Hardcoded configurations: YAML
Duplicated logic: EventDispatcher
PHP & HTML mixed together: Twig
Duplicate form logic, spagetti code: Validator (Fuel)
Other improvements: Mailer, HTTPFoundation,
Translation & Validator
MESSY STRUCTURE & PROCEDURAL CODE
CLASS LOADER
LAYING THE FOUNDATIONS
Controllers
PSR-0
  Namespace the code
  Restructure into a better directory heirarchy
  Component based structure for our own code too
USAGE
$aepcs=ary
 nmsae   ra(
   'edraeaepc'= _DR_./,
    VnoNmNmsae > _I_ ''
   'edraenteNmsae = _DR_./
    VnoNmAohraepc' > _I_ ''
);

$odr=nwyfnopnnlsLaenvraCasodr)
lae   e SmoyCmoetCasodrUiesllsLae(;
$odr>eitr)
lae-rgse(;
$odr>eitraepcs$aepcs;
lae-rgseNmsae(nmsae)
CACHING
Support for APC available, just needs to be enabled
GLOBALS, SINGLETONS AND CRAZY OBJECTS
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.
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
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];
  };
SHARING OBJECTS
$otie[d' =$otie-saefnto(c {
cnanr'b]   cnanr>hr(ucin$)
    rtr nwD(..,$[d_sr] $[d_w')
     eun e PO"." c'bue', c'bpd];
};
)
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;
     }
}
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
    }
 }
CONTROLLER REFACTORING (BEFORE)
<pp
 ?h
casSmCnrle
 ls oeotolr
{
     / ..
      / .

      pbi fnto smAto(
       ulc ucin oecin)
      {
           $oe =nwSmMdl$hs>otie)
            mdl  e oeoe(ti-cnanr;
      }
}
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')
        };
         )
    }
}
CONTROLLER REFACTORING (AFTER)
<pp
 ?h
casSmCnrle
 ls oeotolr
{
     / ..
      / .

     pbi fnto smAto(
      ulc ucin oecin)
     {
          $oe =$hs>otie[fcois]'oemdl]>e
           mdl  ti-cnanr'atre'[sm_oe'-nw
Mdl)
 oe(;
     }
}
HARDCODED CONFIGURATIONS
YAML
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'
PARSING A YAML FILE
$al=nwSmoyCmoetYmasr)
ym   e yfnopnnalPre(;

$asdstig =$al>as(iegtcnet(_I_./ofgyl)
 pre_etns  ym-prefl_e_otns_DR_'cni.m')
;
CACHING
  :-(
SCATTERED ROUTING LOGIC, LONG IF/ELSE
            CONDITIONS
ROUTING
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)
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;
ROUTES FILE
idx
ne:
 pten /
  atr:
 dfut:{cas 'rjcttcCnrle' mto:'oeae }
  eals   ls: PoetSaiotolr, ehd hmPg'
 rqieet:
  eurmns
  _ehd GT
   mto: E
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
}
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'(;
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;
   }
}
ROUTE CACHING
$otr=nwRuigRue(e YmFlLae(lctr,'otsyl,
rue   e otnotrnw alieodr$oao) rue.m'
ary'ah_i'= 'vrwwcce',$otx)
ra(ccedr > /a/w/ah/) cnet;
UTM DATA, ETC
 $r =pe_elc(/?t_.?[&+' ',$r)
 ul   rgrpae'&um(*)=^]/, ' ul;
 $r =(usr$r,-)= '' ?rrm$r,'' :$r;
 ul   sbt(ul 1 = ?) ti(ul ?)   ul


http://forums.phpfreaks.com/topic/257622-remove-utm-
                  tags-from-url-regex/
DUPLICATED LOGIC
EVENT DISPATCHER
WHY?
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
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!
APPROACH
NotifiableMessageInterface
RequestRedirection event
RedirectableNotification event (extends and implements
the above)
Events must extend the symfony event
NOTIFIABLE MESSAGE INTERFACE
<pp
?h
nmsaePoetFaeokEet;
aepc rjcrmwrvns

itraeNtfalMsaenefc
 nefc oiibeesgItrae
{
  pbi fnto gtoiiain)
   ulc ucin eNtfcto(;

    / tehm cast b apid
     / h tl ls o e ple
    pbi fnto gtls(;
     ulc ucin eCas)
}
REQUEST REDIRECTION EVENT
<pp
 ?h
nmsaePoetFaeokEet;
 aepc rjcrmwrvns
ueSmoyCmoetEetipthrEet
 s yfnopnnvnDsacevn;
casRqeteieto etnsEet
 ls eusRdrcin xed vn
{
   poetd$r;
    rtce ul

    pbi fnto _cntut$r =nl)
     ulc ucin _osrc(ul  ul
    {
       $hs>r =$r;
        ti-ul  ul
    }

    pbi fnto gtR(
     ulc ucin eUL)
    {
       rtr $hs>r;
        eun ti-ul
    }
}
LISTENER
<pp
?h
nmsaePoetFaeokLsees
aepc rjcrmwritnr;

uePoetFaeokEet;
s rjcrmwrvns
ueSmoyCmoetEetipthrEet
s yfnopnnvnDsacevn;

casStessatoiiain
 ls ePritnNtfcto
{
   pbi fnto stoiiain EetoiibeesgItrae$
    ulc ucin eNtfcto( vnsNtfalMsaenefc e
vn )
 et
   {
      $SSIN'ytmntfcto' =$vn-gtoiiain)
       _ESO[sse_oiiain]  eet>eNtfcto(;
      $SSIN'ytmntfcto_ls' =$vn-gtls(;
       _ESO[sse_oiiaincas]  eet>eCas)
   }

}
ANOTHER LISTENER
<pp
?h
nmsaePoetFaeokLsees
aepc rjcrmwritnr;

uePoetFaeokEet;
s rjcrmwrvns
ueSmoyCmoetEetipthrEet
s yfnopnnvnDsacevn;

casRdrc
 ls eiet
{
   pbi fnto rdrcUe(EeteusRdrcin$vn )
    ulc ucin eietsr vnsRqeteieto eet
   {
      / TD:uiiehtfaeok
       / OO tls tprmwr
      hae(Lcto:".$vn-gtR( )
       edr"oain    eet>eUL) ;
      ei(;
       xt)
   }

}
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
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;
  )
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;
GOTCHAS
get/set Name
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
      }
  }
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(;
 }
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)
  }
}
PHP & HTML MIXED TOGETHER
TWIG
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')
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
     }
}
PIMPLE ISSUE / ADD GLOBAL
TWIG TEMPLATES
{ sm_aibe}
 { oevral }

{ sm cmet#
 # oe omn }

{ stls_fies=vral.eIes)%
 % e ito_tm aibegttm( }

{ frie i ls_fies%
 % o tm n ito_tm }
     <i{lo.ne}:{ie.ae}/i
      l>{opidx} {tmnm}<l>
{ es %
 % le }
     <iEpy:(/i
      l>mt -<l>
{ edo %
 % nfr }
TEMPLATE CACHING
    This caches compiled templates not output
$hs>wg=nwwgEvrnet$odr ary
ti-ti   e Ti_niomn(lae, ra(
         'ah'= 'vrwwccetmlts,
          cce > /a/w/ah/epae/
      );
      )
OUTPUT CACHING
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;
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
     }
}
VALIDATOR (FUEL)
There is a symfony component which does this, though we
         opted for the Fuel validation component.
HTTPFOUNDATION
Abstracting superglobals, the HTTP request and the HTTP
                        response
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
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
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(;
TRANSLATION
Worth a mention
SWIFT MAILER
SMTP TRANSPORT
$rnpr =wf_mprnpr:nwntne$otie[stig'[s
tasot   SitStTasot:eIsac(cnanr'etns]'m
t'[hs',2)
p]'ot] 5
       -stsrae$otie[stig'[st'[ue')
       >eUenm(cnanr'etns]'mp]'sr]
       -stasod$otie[stig'[st'[ps')
       >ePswr(cnanr'etns]'mp]'as];
CREATE THE MESSAGE
$hs>esg =wf_esg:nwntne$ujc)
ti-msae  SitMsae:eIsac(sbet
    -strmary$rm= $rmnm)
     >eFo(ra(fo > fo_ae)
    -stoary$eiin = $eiin_ae)
     >eT(ra(rcpet > rcpetnm)
    -stoy$oy $otn_ye;
     >eBd(bd, cnettp)
SEND THE MESSAGE
$alr=wf_alr:eIsac(tasot;
mie   SitMie:nwntne$rnpr)

rtr $alr>ed$esg)
eun mie-sn(msae;
THANKS!
    @MICHAELPEACOCK
WWW.MICHAELPEACOCK.CO.UK
  HTTPS://JOIND.IN/8046
IMAGE CREDITS
http://www.flickr.com/photos/oskay/275142789/
http://www.flickr.com/photos/martin_bircher/5287769680/
http://www.flickr.com/photos/tronixstuff/5122815499/
http://www.flickr.com/photos/tronixstuff/4581416773/
http://www.flickr.com/photos/oskay/437339684/
http://www.flickr.com/photos/oskay/437342078/
http://www.flickr.com/photos/laughingsquid/2885196845/

Mais conteúdo relacionado

Mais procurados

Parsing JSON with a single regex
Parsing JSON with a single regexParsing JSON with a single regex
Parsing JSON with a single regexbrian d foy
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giantsIan Barber
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersIan Barber
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
ZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 VersionZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 VersionIan Barber
 
ZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleIan Barber
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scriptingTony Fabeen
 
The Magic Of Tie
The Magic Of TieThe Magic Of Tie
The Magic Of Tiebrian d foy
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of SmartmatchAndrew Shitov
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The AnswerIan Barber
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveEleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]Eleanor McHugh
 
Get into the FLOW with Extbase
Get into the FLOW with ExtbaseGet into the FLOW with Extbase
Get into the FLOW with ExtbaseJochen Rau
 
Operation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRobotoOperation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRobotoSeyed Jafari
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 

Mais procurados (20)

Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
Parsing JSON with a single regex
Parsing JSON with a single regexParsing JSON with a single regex
Parsing JSON with a single regex
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
ZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 VersionZeroMQ Is The Answer: DPC 11 Version
ZeroMQ Is The Answer: DPC 11 Version
 
ZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made Simple
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
The Magic Of Tie
The Magic Of TieThe Magic Of Tie
The Magic Of Tie
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The Answer
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Get into the FLOW with Extbase
Get into the FLOW with ExtbaseGet into the FLOW with Extbase
Get into the FLOW with Extbase
 
03 tk2123 - pemrograman shell-2
03   tk2123 - pemrograman shell-203   tk2123 - pemrograman shell-2
03 tk2123 - pemrograman shell-2
 
Operation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRobotoOperation Flow @ ChicagoRoboto
Operation Flow @ ChicagoRoboto
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 

Destaque

Dance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkDance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkMichael Peacock
 
PHP Continuous Data Processing
PHP Continuous Data ProcessingPHP Continuous Data Processing
PHP Continuous Data ProcessingMichael Peacock
 
Powerful and flexible templates with Twig
Powerful and flexible templates with Twig Powerful and flexible templates with Twig
Powerful and flexible templates with Twig Michael Peacock
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHPMichael Peacock
 

Destaque (7)

Dance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech TalkDance for the puppet master: G6 Tech Talk
Dance for the puppet master: G6 Tech Talk
 
PHP Continuous Data Processing
PHP Continuous Data ProcessingPHP Continuous Data Processing
PHP Continuous Data Processing
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
 
PHP & Twilio
PHP & TwilioPHP & Twilio
PHP & Twilio
 
Powerful and flexible templates with Twig
Powerful and flexible templates with Twig Powerful and flexible templates with Twig
Powerful and flexible templates with Twig
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHP
 
Multimedia chapter 2
Multimedia chapter 2Multimedia chapter 2
Multimedia chapter 2
 

Semelhante a Refactoring to symfony components

Nginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with LuaNginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with LuaTony Fabeen
 
One page app with AngularJS
One page app with AngularJSOne page app with AngularJS
One page app with AngularJSAdam Štipák
 
Proxy OOP Pattern in PHP
Proxy OOP Pattern in PHPProxy OOP Pattern in PHP
Proxy OOP Pattern in PHPMarco Pivetta
 
Create Custom Post Type Plugin
Create Custom Post Type PluginCreate Custom Post Type Plugin
Create Custom Post Type PluginJan Wilson
 
Automated tests - facts and myths
Automated tests - facts and mythsAutomated tests - facts and myths
Automated tests - facts and mythsWojciech Sznapka
 
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...Ari Lerner
 
Angular.js + Rails at WeWork or: The Accidental Feature
Angular.js + Rails at WeWork or: The Accidental FeatureAngular.js + Rails at WeWork or: The Accidental Feature
Angular.js + Rails at WeWork or: The Accidental FeatureJonathan Magen
 
Beginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at GoogleBeginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at GoogleAri Lerner
 
R57shell
R57shellR57shell
R57shellady36
 
Creating windows store java script apps
Creating windows store java script appsCreating windows store java script apps
Creating windows store java script appsEugene Zharkov
 
Marko Gargenta_Remixing android
Marko Gargenta_Remixing androidMarko Gargenta_Remixing android
Marko Gargenta_Remixing androidDroidcon Berlin
 
Drupal 8 in action, the route to the method
Drupal 8 in action, the route to the methodDrupal 8 in action, the route to the method
Drupal 8 in action, the route to the methodjuanolalla
 
SecureSocial - Authentication for Play Framework
SecureSocial - Authentication for Play FrameworkSecureSocial - Authentication for Play Framework
SecureSocial - Authentication for Play Frameworkjaliss
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best PracticesEdorian
 
Itsecteam shell
Itsecteam shellItsecteam shell
Itsecteam shellady36
 
Testing TYPO3 Applications
Testing TYPO3 ApplicationsTesting TYPO3 Applications
Testing TYPO3 ApplicationsAndré Wuttig
 
Shell Script Disk Usage Report and E-Mail Current Threshold Status
Shell Script  Disk Usage Report and E-Mail Current Threshold StatusShell Script  Disk Usage Report and E-Mail Current Threshold Status
Shell Script Disk Usage Report and E-Mail Current Threshold StatusVCP Muthukrishna
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2ady36
 

Semelhante a Refactoring to symfony components (20)

Nginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with LuaNginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with Lua
 
One page app with AngularJS
One page app with AngularJSOne page app with AngularJS
One page app with AngularJS
 
Proxy OOP Pattern in PHP
Proxy OOP Pattern in PHPProxy OOP Pattern in PHP
Proxy OOP Pattern in PHP
 
Create Custom Post Type Plugin
Create Custom Post Type PluginCreate Custom Post Type Plugin
Create Custom Post Type Plugin
 
Automated tests - facts and myths
Automated tests - facts and mythsAutomated tests - facts and myths
Automated tests - facts and myths
 
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
How to create a 3.2 billion dollar business in 20 minutes: combining AngularJ...
 
Angular.js + Rails at WeWork or: The Accidental Feature
Angular.js + Rails at WeWork or: The Accidental FeatureAngular.js + Rails at WeWork or: The Accidental Feature
Angular.js + Rails at WeWork or: The Accidental Feature
 
Beginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at GoogleBeginner workshop to angularjs presentation at Google
Beginner workshop to angularjs presentation at Google
 
R57shell
R57shellR57shell
R57shell
 
Creating windows store java script apps
Creating windows store java script appsCreating windows store java script apps
Creating windows store java script apps
 
Marko Gargenta_Remixing android
Marko Gargenta_Remixing androidMarko Gargenta_Remixing android
Marko Gargenta_Remixing android
 
Drupal 8 in action, the route to the method
Drupal 8 in action, the route to the methodDrupal 8 in action, the route to the method
Drupal 8 in action, the route to the method
 
Ae internals
Ae internalsAe internals
Ae internals
 
SecureSocial - Authentication for Play Framework
SecureSocial - Authentication for Play FrameworkSecureSocial - Authentication for Play Framework
SecureSocial - Authentication for Play Framework
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
 
Itsecteam shell
Itsecteam shellItsecteam shell
Itsecteam shell
 
Testing TYPO3 Applications
Testing TYPO3 ApplicationsTesting TYPO3 Applications
Testing TYPO3 Applications
 
Shell Script Disk Usage Report and E-Mail Current Threshold Status
Shell Script  Disk Usage Report and E-Mail Current Threshold StatusShell Script  Disk Usage Report and E-Mail Current Threshold Status
Shell Script Disk Usage Report and E-Mail Current Threshold Status
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2
 
2013 - Benjamin Eberlei - Doctrine 2
2013 - Benjamin Eberlei - Doctrine 22013 - Benjamin Eberlei - Doctrine 2
2013 - Benjamin Eberlei - Doctrine 2
 

Mais de Michael Peacock

Immutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and TerraformImmutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and TerraformMichael Peacock
 
Test driven APIs with Laravel
Test driven APIs with LaravelTest driven APIs with Laravel
Test driven APIs with LaravelMichael Peacock
 
Symfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning TalkSymfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning TalkMichael Peacock
 
Alexa, lets make a skill
Alexa, lets make a skillAlexa, lets make a skill
Alexa, lets make a skillMichael Peacock
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with LaravelMichael Peacock
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel PassportMichael Peacock
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Evolution of a big data project
Evolution of a big data projectEvolution of a big data project
Evolution of a big data projectMichael Peacock
 
Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Michael Peacock
 
Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Michael Peacock
 
Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012Michael Peacock
 
PHP North East Registry Pattern
PHP North East Registry PatternPHP North East Registry Pattern
PHP North East Registry PatternMichael Peacock
 
PHP North East - Registry Design Pattern
PHP North East - Registry Design PatternPHP North East - Registry Design Pattern
PHP North East - Registry Design PatternMichael Peacock
 
Supermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talkSupermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talkMichael Peacock
 
Corporate Structures - September 2010
Corporate Structures - September 2010Corporate Structures - September 2010
Corporate Structures - September 2010Michael Peacock
 
PHP North-East - Automated Deployment
PHP North-East - Automated DeploymentPHP North-East - Automated Deployment
PHP North-East - Automated DeploymentMichael Peacock
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised contentMichael Peacock
 

Mais de Michael Peacock (19)

Immutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and TerraformImmutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and Terraform
 
Test driven APIs with Laravel
Test driven APIs with LaravelTest driven APIs with Laravel
Test driven APIs with Laravel
 
Symfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning TalkSymfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning Talk
 
Alexa, lets make a skill
Alexa, lets make a skillAlexa, lets make a skill
Alexa, lets make a skill
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with Laravel
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel Passport
 
Vagrant
VagrantVagrant
Vagrant
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Evolution of a big data project
Evolution of a big data projectEvolution of a big data project
Evolution of a big data project
 
Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012
 
Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012
 
Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012
 
Supermondays twilio
Supermondays twilioSupermondays twilio
Supermondays twilio
 
PHP North East Registry Pattern
PHP North East Registry PatternPHP North East Registry Pattern
PHP North East Registry Pattern
 
PHP North East - Registry Design Pattern
PHP North East - Registry Design PatternPHP North East - Registry Design Pattern
PHP North East - Registry Design Pattern
 
Supermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talkSupermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talk
 
Corporate Structures - September 2010
Corporate Structures - September 2010Corporate Structures - September 2010
Corporate Structures - September 2010
 
PHP North-East - Automated Deployment
PHP North-East - Automated DeploymentPHP North-East - Automated Deployment
PHP North-East - Automated Deployment
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised content
 

Refactoring to symfony components

  • 1. REFACTORING TO SYMFONY COMPONENTS ...AND THEIR FRIENDS Michael Peacock
  • 2. @MICHAELPEACOCK Head Developer @ Ground Six Technical author Occasional conference speaker
  • 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
  • 8. OUR REFACTORING TALE SPEED UP DEVELOPMENT & MODERNISE LEGACY CODEBASE
  • 9. OUR JOURNEY Messy structure, some procedural code: ClassLoader Globals, singletons and crazy objects: Pimple Scattered routing logic, long if/else conditions: Routing Hardcoded configurations: YAML Duplicated logic: EventDispatcher PHP & HTML mixed together: Twig Duplicate form logic, spagetti code: Validator (Fuel) Other improvements: Mailer, HTTPFoundation, Translation & Validator
  • 10. MESSY STRUCTURE & PROCEDURAL CODE
  • 12. LAYING THE FOUNDATIONS Controllers PSR-0 Namespace the code Restructure into a better directory heirarchy Component based structure for our own code too
  • 13. USAGE $aepcs=ary nmsae ra( 'edraeaepc'= _DR_./, VnoNmNmsae > _I_ '' 'edraenteNmsae = _DR_./ VnoNmAohraepc' > _I_ '' ); $odr=nwyfnopnnlsLaenvraCasodr) lae e SmoyCmoetCasodrUiesllsLae(; $odr>eitr) lae-rgse(; $odr>eitraepcs$aepcs; lae-rgseNmsae(nmsae)
  • 14. CACHING Support for APC available, just needs to be enabled
  • 15. GLOBALS, SINGLETONS AND CRAZY OBJECTS
  • 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]; };
  • 19. SHARING OBJECTS $otie[d' =$otie-saefnto(c { cnanr'b] cnanr>hr(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') }; ) } }
  • 24. CONTROLLER REFACTORING (AFTER) <pp ?h casSmCnrle ls oeotolr { / .. / . pbi fnto smAto( ulc ucin oecin) { $oe =$hs>otie[fcois]'oemdl]>e mdl ti-cnanr'atre'[sm_oe'-nw Mdl) oe(; } }
  • 26. YAML
  • 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') ;
  • 30. SCATTERED ROUTING LOGIC, LONG IF/ELSE CONDITIONS
  • 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;
  • 34. ROUTES FILE idx ne: pten / atr: dfut:{cas 'rjcttcCnrle' mto:'oeae } eals ls: PoetSaiotolr, ehd hmPg' rqieet: eurmns _ehd GT mto: E
  • 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; } }
  • 38. ROUTE CACHING $otr=nwRuigRue(e YmFlLae(lctr,'otsyl, rue e otnotrnw alieodr$oao) rue.m' ary'ah_i'= 'vrwwcce',$otx) ra(ccedr > /a/w/ah/) cnet;
  • 39. UTM DATA, ETC $r =pe_elc(/?t_.?[&+' ',$r) ul rgrpae'&um(*)=^]/, ' ul; $r =(usr$r,-)= '' ?rrm$r,'' :$r; ul sbt(ul 1 = ?) ti(ul ?) ul http://forums.phpfreaks.com/topic/257622-remove-utm- tags-from-url-regex/
  • 42. WHY?
  • 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!
  • 45. APPROACH NotifiableMessageInterface RequestRedirection event RedirectableNotification event (extends and implements the above) Events must extend the symfony event
  • 46. NOTIFIABLE MESSAGE INTERFACE <pp ?h nmsaePoetFaeokEet; aepc rjcrmwrvns itraeNtfalMsaenefc nefc oiibeesgItrae { pbi fnto gtoiiain) ulc ucin eNtfcto(; / tehm cast b apid / h tl ls o e ple pbi fnto gtls(; ulc ucin eCas) }
  • 47. REQUEST REDIRECTION EVENT <pp ?h nmsaePoetFaeokEet; aepc rjcrmwrvns ueSmoyCmoetEetipthrEet s yfnopnnvnDsacevn; casRqeteieto etnsEet ls eusRdrcin xed vn { poetd$r; rtce ul pbi fnto _cntut$r =nl) ulc ucin _osrc(ul ul { $hs>r =$r; ti-ul ul } pbi fnto gtR( ulc ucin eUL) { rtr $hs>r; eun ti-ul } }
  • 48. LISTENER <pp ?h nmsaePoetFaeokLsees aepc rjcrmwritnr; uePoetFaeokEet; s rjcrmwrvns ueSmoyCmoetEetipthrEet s yfnopnnvnDsacevn; casStessatoiiain ls ePritnNtfcto { pbi fnto stoiiain EetoiibeesgItrae$ ulc ucin eNtfcto( vnsNtfalMsaenefc e vn ) et { $SSIN'ytmntfcto' =$vn-gtoiiain) _ESO[sse_oiiain] eet>eNtfcto(; $SSIN'ytmntfcto_ls' =$vn-gtls(; _ESO[sse_oiiaincas] eet>eCas) } }
  • 49. ANOTHER LISTENER <pp ?h nmsaePoetFaeokLsees aepc rjcrmwritnr; uePoetFaeokEet; s rjcrmwrvns ueSmoyCmoetEetipthrEet s yfnopnnvnDsacevn; casRdrc ls eiet { pbi fnto rdrcUe(EeteusRdrcin$vn ) ulc ucin eietsr vnsRqeteieto eet { / TD:uiiehtfaeok / OO tls tprmwr hae(Lcto:".$vn-gtR( ) edr"oain eet>eUL) ; ei(; xt) } }
  • 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) } }
  • 57. PHP & HTML MIXED TOGETHER
  • 58. TWIG
  • 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 } }
  • 61. PIMPLE ISSUE / ADD GLOBAL
  • 62. TWIG TEMPLATES { sm_aibe} { oevral } { sm cmet# # oe omn } { stls_fies=vral.eIes)% % e ito_tm aibegttm( } { frie i ls_fies% % o tm n ito_tm } <i{lo.ne}:{ie.ae}/i l>{opidx} {tmnm}<l> { es % % le } <iEpy:(/i l>mt -<l> { edo % % nfr }
  • 63. TEMPLATE CACHING This caches compiled templates not output $hs>wg=nwwgEvrnet$odr ary ti-ti e Ti_niomn(lae, ra( 'ah'= 'vrwwccetmlts, cce > /a/w/ah/epae/ ); )
  • 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.
  • 68. HTTPFOUNDATION Abstracting superglobals, the HTTP request and the HTTP response
  • 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(;
  • 74. SMTP TRANSPORT $rnpr =wf_mprnpr:nwntne$otie[stig'[s tasot SitStTasot:eIsac(cnanr'etns]'m t'[hs',2) p]'ot] 5 -stsrae$otie[stig'[st'[ue') >eUenm(cnanr'etns]'mp]'sr] -stasod$otie[stig'[st'[ps') >ePswr(cnanr'etns]'mp]'as];
  • 75. CREATE THE MESSAGE $hs>esg =wf_esg:nwntne$ujc) ti-msae SitMsae:eIsac(sbet -strmary$rm= $rmnm) >eFo(ra(fo > fo_ae) -stoary$eiin = $eiin_ae) >eT(ra(rcpet > rcpetnm) -stoy$oy $otn_ye; >eBd(bd, cnettp)
  • 76. SEND THE MESSAGE $alr=wf_alr:eIsac(tasot; mie SitMie:nwntne$rnpr) rtr $alr>ed$esg) eun mie-sn(msae;
  • 77. THANKS! @MICHAELPEACOCK WWW.MICHAELPEACOCK.CO.UK HTTPS://JOIND.IN/8046