Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Modernisation of Legacy PHP Applications to Symfony2 - Symfony Live Berlin 2012


Published on

PHP and its community has evolved really fast in the last few years to allow for professional architectures and solutions. However, there are thousands of existing PHP applications which have not evolved in the meantime and are now crippled and unmaintainable because of that. These applications represent a real threat to the competitiveness of the business that relies on them.
The best approach in terms of business to solve this problem is progressive rewrite. Symfony2 and its modular architecture make it possible. This talk will cover the main technical difficulties of the progressive approach when rewriting legacy PHP applications using Symfony2

Published in: Technology

Modernisation of Legacy PHP Applications to Symfony2 - Symfony Live Berlin 2012

  1. 1. Modernisa0on  of  legacy  PHP  applica0ons     using  Symfony2     23/11/2012   1   THEODO  
  2. 2. The  need  for  progressive  rewrite    The  technical  challenges  and  our  solu0ons    The  future   23/11/2012   2   THEODO  
  3. 3. Legacy  PHP  applica9ons  are  everywhere   History  of  PHP  applica9ons  •  79%  :  websites  wriBen  in  PHP  among  the  top  1  million,  according   to  •  1994:  PHP  was  created.  Start  of  the  SpageBhi  age  •  2004:  PHP5  was  released  •  2007:  ZF  1.0.0  and  SF  1.0  were  released.  Start  of  the  MVC  age   13  years  of  (mostly)  spageBhi-­‐coded  web-­‐apps     23/11/2012   3   THEODO  
  4. 4. How  do  these  applica9ons  cope  with  evolu9ons?   The  need  for  rewrite    •  Many  businesses  rely  on  web  apps  wriBen  during  the  spageBhi  age  •  Making  legacy  applica0ons  evolve  in  a  «  fast  »  way  becomes   impossible.  This  threatens  the  businesses  that  rely  on  them.     Before  the  big  used  to  eat  the  small,   nowadays  it  is  the  fast  who  eat  the  slow    •  What  they  lack  is  a  well-­‐designed  decoupled  and  tested   architecture  that  would  bring  flexibility  of  evolu0on.   23/11/2012   4   THEODO  
  5. 5. Star9ng  a  new  version  from  scratch  is  a  danger  to  the  business   The  dangers  of  total  rewrite    •  New  developments  are  invisible  un0l  the  new  version  is  finished  •  You  need  twice  more  developers:  one  team  to  maintain  the  old   applica0on,  while  the  second  team  is  wri0ng  the  new  version  •  The  probability  of  forge]ng  features  during  the  rewrite  is  high  •  Transi0on  when  the  new  version  is  ready  becomes  costly  and   very  dangerous:  everything  is  impacted  at  once   23/11/2012   5   THEODO  
  6. 6. Progressive  rewrite  is  the  solu9on…  but  is  very  challenging   The  challenge  of  progressive  rewrite    •  You  have  to  work  with  hard-­‐to-­‐read  code  •  All  the  aspects  of  an  applica0on  in  produc0on  are  concerned:     Ø  source  code  of  course   Ø  system   Ø  data   Ø  cache   Ø  remote  webservices,  etc.  •  The  major  conceptual  challenge  in  all  those  aspects  is  decoupling   of  modules.  Just  like  in  scaling!   23/11/2012   6   THEODO  
  7. 7. Progressive rewrite is more profitable Unbeatable  9me-­‐to-­‐market  Functionalities Functionalities Evolu9on   Time Time •  No new features for months •  Only 1 app to maintain •  2 apps to maintain •  Lower regression risks •  Unbeatable time-to-market 23/11/2012   7   THEODO  
  8. 8. The  need  for  progressive  rewrite    The  technical  challenges  and  our  solu0ons    The  future   23/11/2012   8   THEODO  
  9. 9. Theodo  Evolu9on   Our  solu9on  at  Theodo  •  R&D  project  started  at  Theodo  in  2012  •  Aims  to  solve  all  these  issues  to  make  app  rewri0ng  agile  again  •  And  help  Symfony2  take  over  the  world!   23/11/2012   9   THEODO  
  10. 10. The  technical  experts  behind  Theodo  Evolu9on  Theodo  Evolu9on  team   23/11/2012   10   THEODO  
  11. 11. The  big  picture  of  the  different  technical  aspects  to  solve   The  technical  challenges  •  Preven0ng  regressions  •  Upgrading  the  system  •  Rou0ng  •  Sharing  the  layout  •  Sharing  the  session/authen0ca0on  •  Decoupling  the  code  •  Migra0ng  the  model  and  data   23/11/2012   11   THEODO  
  12. 12. Preven0ng  regressions   23/11/2012   12   THEODO  
  13. 13. Belt  and  straps  are  necessary…  and  won’t  be  enough…  Preven9ng  regressions   23/11/2012   13   THEODO  
  14. 14. Func9onnaly  test  what  could  harm  your  business   Preven9ng  regressions  •  By  defini0on,  spaghe]  code  is  deeply  coupled.  Touching  one   part  breaks  something  at  the  other  end  •  Create  func0onal  tests  on  the  most  cri0cal  scenarios  •  Mink  +  ZombieJS:  hBps://   23/11/2012   14   THEODO  
  15. 15. Setup  external  monitoring  and  a  fast  deployment  pipeline   Preven9ng  regressions  The  most  thorough  func0onal  tes0ng  is  done...  by  pu]ng  in  produc0on!    •  Monitor  produc0on  well  •  Deploy  ohen  and  small  updates  •  Setup  a  fast  rollback  system  •  Setup  a  fast  deployment  system,  because  you  want  to  make  it  faster   to  correct  small  problems  than  to  rollback   23/11/2012   15   THEODO  
  16. 16. Upgrading  the  system   23/11/2012   16   THEODO  
  17. 17. Migrate  to  a  modern  environment  that  supports  Symfony2     …and  improves  performance  as  a  bonus.   Upgrading  the  system  •  Symfony2  requires:   •  PHP  5.3.3   •  Sqlite3,  JSON,  ctype   •  date.0mezone  set  in  php.ini  •  php  app/check.php   23/11/2012   17   THEODO  
  18. 18. Check  that  the  legacy  code  will  support  PHP  5.3/5.4   Upgrading  the  system  •  Phpcs  CodeSniffs  for  5.3  and  5.4  compa0bility:   hBps://    •  Setup  a  pre-­‐produc0on  environment  in  the  upgraded   environment  and  run  your  func0onal  tests  on  it  •  And  this  0me  provision  your  environment  with  Puppet  or  Chef!   Check  Blueprint:  hBps://   23/11/2012   18   THEODO  
  19. 19. Rou0ng  23/11/2012   19   THEODO  
  20. 20. Rou9ng  between  the  old  and  the  new   Rou9ng  •  The  beauty  of  PHP:  some  legacy  apps  have  simply  no  rou0ng  system!  •  Host  the  new  app  next  to  the  old  app,  with  clear  URL  differences,  and   proxy  at  the  server  level   •  Subdomain:   •  Subfolder:  •  My  favourite:  create  a  catchall  route  with  Symfony2   23/11/2012   20   THEODO  
  21. 21. The  CatchAll  Route  Rou9ng   class LegacyController extends Controller! {!     /**!      * @Route("/{filename}.php", name="_proxy")!      */!     public function proxyAction($filename)!     {!         ob_start();!         include $filename . .php;! !         return new Response(ob_get_clean());!     }! }! 23/11/2012   21   THEODO  
  22. 22. Rou9ng  from  the  new  to  the  legacy   Rou9ng  •  If  you  have  a  rou0ng  system  in  the  legacy,  you  need  to  boot  it  •  For  Symfony1,  create  a  twig  extension  to  use  «  url_for  »  in  your  new   templates  •  Don’t  forget:     sfConfig::set(sf_no_script_name, true);   23/11/2012   22   THEODO  
  23. 23. Sharing  the  layout  23/11/2012   23   THEODO  
  24. 24. For  end-­‐users  «  progressive  rewrite  »  =  «  same  template  »   Sharing  the  layout    •  Copy-­‐pas0ng  the  layout  is  not  a  good  solu0on  •  Our  solu0on  :  crawl  the  legacy  layout  and  include  it  as  ESIs   ! <esi:include src="{{ path(legacylayout_top) }}" />! ! {% block body %}{% endblock %}! ! <esi:include src="{{ path(legacylayout_bottom) }}" />! ! 23/11/2012   24   THEODO  
  25. 25. The  «  crawling  »  part  of  the  ESI  sub-­‐request   Sharing  the  layout  !    $this->client->setHeader(Cookie, $currentCookie);    if ($request->headers->has(authorization)) {        $this->client->setHeader(            Authorization,            $request->headers->get(authorization)        );    }    if ($this->session->isStarted()) {        $this->session->save();    }    $this->client->request(GET, $url);    $esiContent = $this->client->getResponse()->getContent(); 23/11/2012   25   THEODO  
  26. 26. Sharing  the  session/authen0ca0on   23/11/2012   26   THEODO  
  27. 27. Make  the  legacy  session  accessible  from  Symfony2   Sharing  the  session/authen9ca9on    •  You  want  to  access  what  your  legacy  app  has  put  in  the  session   from  within  Symfony2…    •  BUT  Symfony2  expects  session  informa0on  to  be  neatly  stored  in   arrays  in  the  «  _sf2_aBributes  »  namespace      to  make  your  legacy  session  accessible,  you  need  to  :   •  register  «  Bags  »  for  each  of  your  legacy  $_SESSION  keys   •  create  a  «  ScalarBag  »  type  when  these  values  are  not  arrays     23/11/2012   27   THEODO  
  28. 28. Example  for  a  Symfony1  Session   Sharing  the  session/authen9ca9on  // onKernelRequest!foreach ( array(symfony/user/sfUser/credentials,! !symfony/user/sfUser/attributes’) as $namespace){!    $bag = new NamespacedAttributeBag($namespace, .);    $bag->setName($namespace);!    $session->registerBag($bag);!}! 23/11/2012   28   THEODO  
  29. 29. Integra9ng  9ghtly  sf1  and  Sf2  authen9ca9on  systems   Sharing  the  session/authen9ca9on    We  have  created  a  great  bundle  for  that!     23/11/2012   29   THEODO  
  30. 30. Decoupling  the  code  23/11/2012   30   THEODO  
  31. 31. A^acking  the  spaghe_  problem  Decoupling  the  code   23/11/2012   31   THEODO  
  32. 32. Decoupling  is  a  major  aspect  of  progressive  rewrite  Decoupling  the  code   23/11/2012   32   THEODO  
  33. 33. Decoupling  is  a  major  aspect  of  progressive  rewrite  Decoupling  the  code   23/11/2012   33   THEODO  
  34. 34. Decoupling  is  a  major  aspect  of  progressive  rewrite  Decoupling  the  code   23/11/2012   34   THEODO  
  35. 35. Decoupling  is  a  major  aspect  of  progressive  rewrite  Decoupling  the  code   23/11/2012   35   THEODO  
  36. 36. Decoupling  is  a  major  aspect  of  progressive  rewrite  Decoupling  the  code   23/11/2012   36   THEODO  
  37. 37. Decoupling  is  a  major  aspect  of  progressive  rewrite  Decoupling  the  code   23/11/2012   37   THEODO  
  38. 38. The  dream  architecture  Decoupling  the  code   23/11/2012   38   THEODO  
  39. 39. What  you  usually  find  Decoupling  the  code   23/11/2012   39   THEODO  
  40. 40. You  need  to  create  the  dream  API  and  slowly  refactor  around  it    Decoupling  the  code   A A P P I A I P I A P I A P I A A P P I I 23/11/2012   40   THEODO  
  41. 41. You  need  to  create  the  dream  API  and  slowly  refactor  around  it    Decoupling  the  code   A A P P I A I P I A P I A P I A A P P I I 23/11/2012   41   THEODO  
  42. 42. You  need  to  create  the  dream  API  and  slowly  refactor  around  it    Decoupling  the  code   A A P P I A I P I A P I A P I A A P P I I 23/11/2012   42   THEODO  
  43. 43. You  need  to  create  the  dream  API  and  slowly  refactor  around  it    Decoupling  the  code   A A P P I A I P I A P I A P I A A P P I I 23/11/2012   43   THEODO  
  44. 44. This  is  called  «  Facade  Pa^ern  »   Decoupling  the  code  Wikipedia  A  facade  is  an  object  that  provides  a  simplified  interface  to  a  larger  body  of  code,  such  as  a  class  library.  A  facade  can:  •  make  a  sohware  library  easier  to  use,  understand  and  test,  since   the  facade  has  convenient  methods  for  common  tasks;  •  make  the  library  more  readable,  for  the  same  reason;  •  reduce  dependencies  of  outside  code  on  the  inner  workings  of  a   library,  since  most  code  uses  the  facade,  thus  allowing  more   flexibility  in  developing  the  system;  •  wrap  a  poorly  designed  collec0on  of  APIs  with  a  single  well-­‐ designed  API  (as  per  task  needs).   23/11/2012   44   THEODO  
  45. 45. Symfony2  Service  Container   Decoupling  the  code  •  With  Symfony2,  the  new  API  of  the  Facade  PaBern  is  a  service  •  Create  a  bundle  for  every  «  module  »  you  iden0fied.  •  Create  a  service  for  every  bundle  you  now  have,  that  will  serve  as   your  Facade  API    •  …  and  start  using  these  services!   23/11/2012   45   THEODO  
  46. 46. Migra0ng  the  model  and  data   23/11/2012   46   THEODO  
  47. 47. A  typical  MySQL  database  is  highly  coupled  Migra9ng  the  model  and  data   23/11/2012   47   THEODO  
  48. 48. Decoupling  a  rela9onal  DB  is  like  a^acking  a  giant  monster  Migra9ng  the  model  and  data   23/11/2012   48   THEODO  
  49. 49. The  classical  solu9on  is  syncing  two  versions  of  the  data  Migra9ng  the  model  and  data   •  Syncing  can  be  done  with  ETL  tools  like  KeBle  or  with  custom  code  in   the  new  applica0on   •  To  avoid  unbearable  headaches,  it  is  highly  recommended  to  write  in   only  one  DB.  Which  means  to  rewrite  parts  of  the  legacy  code  to  save,   update  and  delete  in  the  new  DB     23/11/2012   49   THEODO    
  50. 50. A  «  bearable  headache  »  solu9on:  Migra9ng  the  model  and  data   Legacy  Applica0on   New  applica0on   Rou0ng   23/11/2012   50   THEODO  
  51. 51. A  «  bearable  headache  »  solu9on:  Migra9ng  the  model  and  data   Legacy  Applica0on   New  applica0on   Rou0ng   23/11/2012   51   THEODO  
  52. 52. MongoDB  and  DoctrineODM  make  it  (a  li^le)  easier   Migra9ng  the  model  and  data    •  Remember:  progressive  rewrite  relies  on  decoupling,  just  like  scaling.   Non-­‐rela0onal  DBs  make  par0al  evolu0ons  easier  in  the  long-­‐term    •  In  a  document  DB  like  MongoDB  you  can  have  in  the  same  collec0on   data  which  coexist  in  different  versions.  •  To  migrate  them  «  just  in  0me  »  use  /**  @MongoDBPreLoad  */  from   the  Doctrine  ODM   23/11/2012   52   THEODO  
  53. 53. The  need  for  progressive  rewrite    The  technical  challenges  and  our  solu0ons    The  future   23/11/2012   53   THEODO  
  54. 54. The  evolu9on  of  Theodo  Evolu9on   Theodo  Evolu9on  strategy  •  The  Theodo  team  is  today  18  and  growing  excellent  web  devs  working   currently  on  6  progressive  rewrites  of  huge  applica0ons  to  Symfony2  •  Every  technical  solu0on  for  progressive  rewrite  to  Symfony2  is   bundled  in  our  project  Theodo  Evolu0on  •  The  goal:  make  it  an  out-­‐of-­‐the-­‐box  solu0on  to  work  on  legacy  apps   without  touching  legacy  code  •  And  that  way  convert  the  whole  PHP  world  to  Symfony2     23/11/2012   54   THEODO  
  55. 55. How  you  can  profit  from  Theodo  Evolu9on?   Theodo  Evolu9on  strategy  •  Some  Theodo  Evolu0on  bundles  will  be  open-­‐ sourced!    •  Use  our  massive  presence  here  today!  Please   ask  ques0ons  to  the  guys  with  the  black   Theodo  hoodies!  •  Contact  us  @theodo  or   23/11/2012   55   THEODO  
  56. 56. Questions ? @theodo www.theodo.frFeedback: 23/11/2012   56   THEODO