Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Managing Legacy Applications With Composer and Laravel

Managing Legacy Applications With Composer and Laravel

All programmers face the challenge of working on a codebase they would've done differently. "I wish I could just start from scratch" you hear them mutter. But is that really the best solution? Is throwing away years of development a good move?

In this talk we will look at the different methods available to upgrade the current spaghetti mess into a well structured Object Orientated dream. Learn how to go about bootstrapping Laravel into your existing codebase, allowing you to slowly upgrade and refactor to a well structured, Composer based MVC system, without any downtime.

Eb4d2ae4f9dcaa0ff1a392a5744e94a2?s=128

Bernhard Breytenbach

September 30, 2016
Tweet

Other Decks in Programming

Transcript

  1. MAINTAINING LEGACY APPLICATIONS WITH COMPOSER AND LARAVEL by Bernhard Breytenbach

  2. ABOUT ME Started with PHP in 2005 Supporter of all

    things Open Source! https://github.com/Xethron Laravel Migrations Generator Developer at MDS Technologies @BBreyten on Twitter joind.in/talk/788d8
  3. WHAT IS LEGACY SOFTWARE? “The secondary value of software is

    its behaviour... It’s achieved when the current software meets the current needs of the current user... But the needs of the users change, and they do so frequently... Thus the primary value of software is its ability to change.” — Robert C. Martin (Uncle Bob)
  4. WHAT IS LEGACY SOFTWARE? Legacy software is software that is

    unable to change easily Software that is difficult to read and reuse
  5. “DON’T MAINTAIN, REWRITE!”

  6. NETSCAPE NAVIGATOR

  7. THE DANGERS OF REWRITE

  8. REFACTORING Refactoring is the process of restructuring existing code without

    changing its external behaviour, in order to improve readability and reduce code complexity, as to improve source code maintainability and create a more expressive internal architecture or object model to improve extensibility. https://en.wikipedia.org/wiki/Code_refactoring
  9. RULES OF REFACTORING Small iterative changes Make sure everything still

    works Send to QA, Push to Production Release regularly (weekly at most) Do the next small change
  10. VERSION CONTROL

  11. DEPLOYMENT

  12. PICK A CODING STANDARD PSR1 / PSR2 / Symfony Only

    one standard php-cs-fixer: https://github.com/FriendsOfPhp/PHP-CS-Fixer
  13. DIRECTORY STRUCTURE public/ src/ vendor/ bootstrap/

  14. MOVE FUNCTIONALITY INTO CLASSES Get rid of includes One class

    per file Files should declare new symbols, or cause side effects, but not do both.
  15. REPLACE MAGIC NUMBERS WITH CONSTANTS i f ( $ s

    t a t u s ­ > i d = = = 1 5 ) i f ( $ u s e r ­ > t y p e = = = 3 ) i f ( $ c o d e = = = 4 1 8 ) i f ( $ s t a t u s ­ > i d = = = S t a t u s : : C A N C E L L E D ) i f ( $ u s e r ­ > t y p e = = = U s e r : : T Y P E _ A D M I N ) i f ( $ c o d e = = = R e s p o n s e : : H T T P _ I _ A M _ A _ T E A P O T )
  16. BREAK UP LARGE CLASSES/FUNCTIONS Large functions is where classes go

    to hide.
  17. PLAN OF ACTION Take Charge! Baby steps Fail fast, fail

    cheap
  18. SETUP AUTOLOADING < ? p h p s p l

    _ a u t o l o a d _ r e g i s t e r ( f u n c t i o n ( $ c l a s s ) { $ p r e f i x = ' F o o \ \ B a r \ \ ' ; $ b a s e _ d i r = _ _ D I R _ _ . ' / s r c / ' ; $ l e n = s t r l e n ( $ p r e f i x ) ; i f ( s t r n c m p ( $ p r e f i x , $ c l a s s , $ l e n ) ! = = 0 ) { r e t u r n ; } $ r e l a t i v e _ c l a s s = s u b s t r ( $ c l a s s , $ l e n ) ; $ f i l e = $ b a s e _ d i r . s t r _ r e p l a c e ( ' \ \ ' , ' / ' , $ r e l a t i v e _ c l a s s ) . ' . p h p ' ; / / i f t h e f i l e e x i s t s , r e q u i r e i t i f ( f i l e _ e x i s t s ( $ f i l e ) ) { r e q u i r e $ f i l e ; } } ) ;
  19. COMPOSER

  20. WHAT IS COMPOSER?

  21. WHY USE COMPOSER?

  22. BUT I CAN WRITE IT MYSELF?

  23. SETTING UP COMPOSER

  24. BOOTSTRAP COMPOSER r e q u i r e "

    v e n d o r / a u t o l o a d . p h p "
  25. LOAD THIRD PARTY LIBRARIES VIA COMPOSER Require third party libraries

    with Composer Look for files using those libraries Make sure they require your bootstrapping file
  26. COMPOSER AUTOLOADING { " a u t o l o

    a d " : { " c l a s s m a p " : [ " l e g a c y ­ c l a s s e s " , " s o m e O t h e r F o l d e r " ] , " p s r ­ 0 " : { " M d s \ \ C o l l i v e r y " : " m y ­ a p p / " , } , " p s r ­ 4 " : { " M d s \ \ V i s a P a k " : " a l s o ­ m y ­ a p p / " , } } }
  27. START USING OTHER THIRD PARTY LIBRARIES! Carbon

  28. SETTING UP LARAVEL

  29. APACHE < V i r t u a l H

    o s t * : 8 0 > D o c u m e n t R o o t / v a r / w w w / l e g a c y / h t d o c s S e r v e r A d m i n b e r n h a r d @ c o f f e e c o d e . c o . z a S e r v e r N a m e w w w . l e g a c y . l o c a l S e r v e r A l i a s l e g a c y . l o c a l T r a n s f e r L o g / v a r / l o g / a p a c h e 2 / l e g a c y _ a c c e s s . l o g E r r o r L o g / v a r / l o g / a p a c h e 2 / l e g a c y _ e r r o r . l o g < D i r e c t o r y / v a r / w w w / l e g a c y / h t d o c s > R e w r i t e E n g i n e O n # R e d i r e c t T r a i l i n g S l a s h e s . . . R e w r i t e R u l e ^ ( . * ) / $ / $ 1 [ L , R = 3 0 1 ] R e w r i t e C o n d % { R E Q U E S T _ F I L E N A M E } ! ­ d R e w r i t e C o n d % { R E Q U E S T _ F I L E N A M E } ! ­ f R e w r i t e R u l e ^ a p p . p h p [ L ] < / D i r e c t o r y > < / V i r t u a l H o s t >
  30. ROUTES < ? p h p R o u t

    e : : g e t ( ' r e g i s t e r ' , R e g i s t e r C o n t r o l l e r : : c l a s s . ' @ i n d e x ' ) ; R o u t e : : g e t ( ' r e g i s t e r . p h p ' , R e g i s t e r C o n t r o l l e r : : c l a s s . ' @ i n d e x ' ) ;
  31. BOOTSTRAPPING LARAVEL < ? p h p u s e

    A c m e \ B o o t s t r a p \ R a v e n S e r v i c e P r o v i d e r ; u s e I l l u m i n a t e \ F i l e s y s t e m \ F i l e s y s t e m ; u s e I l l u m i n a t e \ F o u n d a t i o n \ P r o v i d e r R e p o s i t o r y ; u s e I l l u m i n a t e \ H t t p \ R e q u e s t ; d a t e _ d e f a u l t _ t i m e z o n e _ s e t ( ' A f r i c a / J o h a n n e s b u r g ' ) ; r e q u i r e _ _ D I R _ _ . ' / a u t o l o a d . p h p ' ; / * * @ v a r \ I l l u m i n a t e \ F o u n d a t i o n \ A p p l i c a t i o n $ a p p * / $ a p p = r e q u i r e _ o n c e _ _ D I R _ _ . ' / a p p . p h p ' ; $ a p p ­ > i n s t a n c e ( ' r e q u e s t ' , R e q u e s t : : c a p t u r e ( ) ) ; $ a p p ­ > b o o t s t r a p W i t h ( [ I l l u m i n a t e \ F o u n d a t i o n \ B o o t s t r a p \ D e t e c t E n v i r o n m e n t : : c l a s s , I l l u m i n a t e \ F o u n d a t i o n \ B o o t s t r a p \ L o a d C o n f i g u r a t i o n : : c l a s s , I l l u m i n a t e \ F o u n d a t i o n \ B o o t s t r a p \ C o n f i g u r e L o g g i n g : : c l a s s , A c m e \ B o o t s t r a p \ H a n d l e E x c e p t i o n s : : c l a s s , I l l u m i n a t e \ F o u n d a t i o n \ B o o t s t r a p \ R e g i s t e r F a c a d e s : : c l a s s , ] ) ; / *
  32. USING LARAVEL OUTSIDE OF LARAVEL

  33. SIMPLE: REQUESTS/COLLECTIONS < ? p h p i f (

    i s s e t ( $ _ G E T [ ' n a m e ' ] ) ) { $ n a m e = $ _ G E T [ ' n a m e ' ] ; } e l s e { $ n a m e = ' D e m o U s e r ' ; } / / ­ ­ ­ $ n a m e = R e q u e s t : : g e t ( ' n a m e ' ) ;
  34. SIMPLE: REQUESTS/COLLECTIONS < ? p h p $ a r

    r a y = n e w \ I l l u m i n a t e \ S u p p o r t \ C o l l e c t i o n ( ) ; $ a r r a y ­ > f i l t e r ( ) ; $ a r r a y ­ > m a p ( ) ; $ a r r a y ­ > r e d u c e ( ) ;
  35. IOC < ? p h p $ c o l

    l i v e r y = a p p ( ' c o l l i v e r y ' ) ;
  36. ELOQUENT/DATABASE < ? p h p $ u s e

    r s = U s e r : : a l l ( ) ; D B : : c o n n e c t i o n ( ' m y s q l ' ) ­ > t a b l e ( ' u s e r s ' ) ­ > w h e r e N u l l ( ' d e l e t e d A t ' ) ­ > g e t ( ) ;
  37. VIEWS < ? p h p $ u s e

    r = A u t h : : u s e r ( ) ; e c h o v i e w ( ' i n d e x ' , c o m p a c t ( ' u s e r ' ) ) ­ > r e n d e r ( ) ;
  38. EMAILS < ? p h p $ h t m

    l m s g h e a d = " < h t m l > < h e a d > < / h e a d > < b o d y > < p > < d i v a l i g n = \ " l e f t \ " w i d t h = \ " 6 0 0 p t ; \ " > < / d i v $ h t m l m s g h e a d . = " < p > < s p a n s t y l e = \ " f o n t ­ s i z e : 1 2 p t ; f o n t ­ f a m i l y : ' A r i a l ' , ' s a n s ­ s e r i f ' \ " $ h t m l m s g f o o t = " < s p a n s t y l e = \ " f o n t ­ s i z e : 1 0 p t ; f o n t ­ f a m i l y : ' A r i a l ' , ' s a n s ­ s e r i f ' \ " > < b r $ h t m l m s g f o o t . = " < s p a n s t y l e = \ " f o n t ­ s i z e : 1 6 p t ; f o n t ­ f a m i l y : ' T i m e N e w R o m a n ' , ' s a n s ­ s e r i $ h t m l m s g f o o t . = " < b r / > " . $ _ S E S S I O N [ ' e m a i l ' ] . " < / s p a n > < p > < b > < s p a n s t y l e = \ " f o n t ­ s i z e : 1 0 p t ; c o l o r : n a v y ; f o n t ­ f a m i l y : ' A r i a l ' , ' s a n s ­ s e r i f ' \ " > < p > < b > < s p a n s t y l e = \ " f o n t ­ s i z e : 1 0 p t ; c o l o r : n a v y ; f o n t ­ f a m i l y : ' A r i a l ' , ' s a n s ­ s e r i f ' \ " > < p > < d i v a l i g n = \ " l e f t \ " w i d t h = \ " 6 0 0 p t ; \ " > < i m g s r c = \ " c i d : m a i l _ b o t t o m \ " > < / d i v > < / p > < / b o d y > < / h t m l > " ; i n c l u d e _ o n c e ' . . / s r c / p h p m a i l e r / c l a s s . p h p m a i l e r . p h p ' ; $ m a i l = n e w P H P M a i l e r ( t r u e ) ; $ m a i l ­ > I s H T M L ( t r u e ) ; $ m a i l ­ > C h a r S e t = " U T F ­ 8 " ; t r y { $ m a i l ­ > A d d A d d r e s s ( $ _ P O S T [ ' e m a i l ' ] , $ _ P O S T [ ' n a m e ' ] ) ; $ m a i l ­ > S e t F r o m ( $ _ S E S S I O N [ ' e m a i l ' ] ) ; $ m a i l ­ > A d d R e p l y T o ( $ _ S E S S I O N [ ' e m a i l ' ] ) ; $ m a i l ­ > A d d E m b e d d e d I m a g e ( ' m a i l _ t o p . p n g ' , ' m a i l _ t o p ' , ' m a i l _ t o p . p n g ' ) ; $ m a i l ­ > A d d E m b e d d e d I m a g e ( ' m a i l _ b o t t o m . p n g ' , ' m a i l _ b o t t o m ' , ' m a i l _ b o t t o m . p n g ' ) ; $ m a i l ­ > S u b j e c t = " G r e e t i n g s P H P J o b u r g ! " ; $ m a i l ­ > M s g H T M L ( $ h t m l m s g h e a d . " " . n l 2 b r ( $ _ P O S T [ ' m e s s a g e ' ] ) . " " . $ h t m l m s g f o o t ) ;
  39. EMAILS < ? p h p t r y {

    $ d a t a = [ ' t o N a m e ' = > R e q u e s t : : g e t ( ' n a m e ' ) , ' f r o m N a m e ' = > $ _ S E S S I O N [ ' n a m e ' ] , ' f r o m E m a i l ' = > $ _ S E S S I O N [ ' e m a i l ' ] , ' h t m l B o d y ' = > n l 2 b r ( R e q u e s t : : g e t ( ' m e s s a g e ' ) ) ] ; M a i l : : s e n d ( ' e m a i l s . s t a n d a r d ' , $ d a t a , f u n c t i o n ( M e s s a g e $ m e s s a g e ) { $ m e s s a g e ­ > f r o m ( $ _ S E S S I O N [ ' e m a i l ' ] , $ _ S E S S I O N [ ' n a m e ' ] ) ­ > t o ( R e q u e s t : : g e t ( ' e m a i l ' ) , R e q u e s t : : g e t ( ' n a m e ' ) ) ­ > r e p l y T o ( $ _ S E S S I O N [ ' e m a i l ' ] ) ­ > s u b j e c t ( ' G r e e t i n g s P H P J o b u r g ! ' ) ; } ) ; p r i n t ( " < d i v c l a s s = \ " s u c c e s s \ " > E m a i l s e n t t o < b > " . R e q u e s t : : g e t ( ' n a m e ' ) . " < / b > o n e m } c a t c h ( E x c e p t i o n $ e r r ) { e c h o $ e r r ­ > g e t M e s s a g e ( ) ; }
  40. CONSOLE COMMANDS

  41. The key to success is not perfection, but making peace

    with the term good enough, and then moving on.