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.

Bernhard Breytenbach

September 30, 2016
Tweet

Other Decks in Programming

Transcript

  1. 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
  2. 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)
  3. WHAT IS LEGACY SOFTWARE? Legacy software is software that is

    unable to change easily Software that is difficult to read and reuse
  4. 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
  5. 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
  6. PICK A CODING STANDARD PSR1 / PSR2 / Symfony Only

    one standard php-cs-fixer: https://github.com/FriendsOfPhp/PHP-CS-Fixer
  7. 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.
  8. 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 )
  9. 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 ; } } ) ;
  10. 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 "
  11. 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
  12. 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 / " , } } }
  13. 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 >
  14. 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 ' ) ;
  15. 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 , ] ) ; / *
  16. 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 ' ) ;
  17. 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 ( ) ;
  18. 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 ' ) ;
  19. 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 ( ) ;
  20. 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 ( ) ;
  21. 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 ) ;
  22. 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 ( ) ; }
  23. The key to success is not perfection, but making peace

    with the term good enough, and then moving on.