Bringing Old Legacy Apps To PHP 7 and Beyond - ZendCon 2016

Bringing Old Legacy Apps To PHP 7 and Beyond - ZendCon 2016

Most developers don't get the luxury of working on a greenfield project using a web framework of their choice. Often times we find ourselves inheriting a legacy codebase or a web app written years ago on a now-defunct web framework. The initial temptation might be, "I'll just rewrite all this in x framework." But hold on my framework friend, a rewrite is costly and is rarely the correct answer. We'll discuss strategies to give that legacy codebase a complete makeover in PHP 7 with incremental changes that keep the business running while improving security, stability, and maintainability of the codebase.

8c090cc1ccd623a146ddd9159b1bf7e2?s=128

Sammy Kaye Powers

October 19, 2016
Tweet

Transcript

  1. Bringing Old Legacy Apps To October 19th, 2016 Sammy Kaye

    Powers @SammyK PHP 7 & Beyond
  2. Codebase @SammyK #zendcon2016 joind.in/talk/6d127

  3. None
  4. I’ll just rewrite this in ____________! @SammyK #zendcon2016 joind.in/talk/6d127

  5. I’ll just rewrite this in ____________! @SammyK #zendcon2016 joind.in/talk/6d127

  6. I’ll just rewrite this in ____________! Laravel @SammyK #zendcon2016 joind.in/talk/6d127

  7. I’ll just rewrite this in ____________! @SammyK #zendcon2016 joind.in/talk/6d127

  8. rewrite from scratch? Why not @SammyK #zendcon2016 joind.in/talk/6d127

  9. Functionality Existing Codebase Fancy-pants rewrite

  10. Functionality Existing Codebase Fancy-pants rewrite

  11. Functionality Existing Codebase Fancy-pants rewrite

  12. Functionality Existing Codebase Fancy-pants rewrite

  13. Functionality Existing Codebase Fancy-pants rewrite

  14. Refactoring Martin Fowler http://martinfowler.com/books/refactoring.html

  15. “Legacy” /leɡəsē/ • Requires an EOL version of PHP •

    No automated tests • Has outdated dependencies • No autoloading • No sign of “single responsibility”
  16. None
  17. “Legacy” We’ll assume …means any code that can be improved

    @SammyK #zendcon2016 joind.in/talk/6d127 (at least for this talk)
  18. Expectations @SammyK #zendcon2016 joind.in/talk/6d127

  19. elePHPant How to eat an

  20. ZERO Step @SammyK #zendcon2016 joind.in/talk/6d127

  21. Around Poke @SammyK #zendcon2016 joind.in/talk/6d127

  22. Around Poke • Composer &/or autoloading? • Documentation? (Look for

    hidden docs!) • Framework/Dependencies? (How out-dated?) • How is database layer implemented? • How is config handled? • How are front-end assets handled? • Are there tests? • Production env (PHP version)
  23. Analysis Static @SammyK #zendcon2016 joind.in/talk/6d127

  24. phploc

  25. phploc

  26. phpcpd

  27. Consider the Stakeholders @SammyK #zendcon2016 joind.in/talk/6d127

  28. Consider the Stakeholders I’ll need 80 hours to refactor the

    user auth & ACL @SammyK #zendcon2016 joind.in/talk/6d127
  29. Consider the Stakeholders • Most critical security holes • Most

    critical bugs • Most critical features • Use data from static analysis Make a plan
  30. ONE Step @SammyK #zendcon2016 joind.in/talk/6d127

  31. Environment Get it running on your local @SammyK #zendcon2016 joind.in/talk/6d127

  32. From Docker to production Chris Tankersley @SammyK #zendcon2016 joind.in/talk/6d127 Today

    @ 5:15PM in Artist 3
  33. Git Get with master original local-config

  34. 5.(wat) @SammyK #zendcon2016 joind.in/talk/6d127

  35. Fix all the errors @SammyK #zendcon2016 joind.in/talk/6d127

  36. None
  37. TWO Step @SammyK #zendcon2016 joind.in/talk/6d127

  38. 7.0 @SammyK #zendcon2016 joind.in/talk/6d127

  39. 7.0 ✓Performance increase PHP 7 features ✓

  40. 7.0

  41. BC is totes amaze

  42. PHP 7.0 enlightenment The path to 7.0 5.6

  43. PHP 7.0 enlightenment The path to 7.0 5.5

  44. PHP 7.0 enlightenment The path to 7.0 5.4

  45. PHP 7.0 enlightenment The path to 7.0 >= 5.3

  46. THREE Step @SammyK #zendcon2016 joind.in/talk/6d127

  47. Fix all the PHP 7 errors @SammyK #zendcon2016 joind.in/talk/6d127

  48. PHP 7.0 Quick tricks to refactor to (in order of

    ease) @SammyK #zendcon2016 joind.in/talk/6d127
  49. PHP 7.0 “Gotchas” ASP and script PHP tags removed <%

    %> <%= %> <script language="php"></script>
  50. PHP 7.0 “Gotchas” removed php://input $HTTP_RAW_POST_DATA instead read from $HTTP_RAW_POST_DATA

    = file_get_contents('php://input');
  51. PHP 7.0 “Gotchas” PHP-4-style constructors deprecated class foo { function

    foo() {} }
  52. PHP 7.0 “Gotchas” PHP-4-style constructors deprecated class foo { function

    __construct() {} }
  53. PHP 7.0 “Gotchas” Some functions got the ax ereg* functions

  54. PHP 7.0 “Gotchas” “There’s a shim for that!”

  55. PHP 7.0 “Gotchas” “There’s a shim for that!” ereg* functions

    bbrala/php7-ereg-shim eregi($pattern, $sub, &$match) preg_match('/'.$pattern.'/i', $sub, $match)
  56. PHP 7.0 “Gotchas” Another one bites the dust ext/mysql functions

  57. PHP 7.0 “Gotchas” “There’s a shim for that!” ext/mysql functions

    dshafik/php7-mysql-shim
  58. PHP 7.0 “Gotchas” Caveats though… ext/mysql functions dshafik/php7-mysql-shim $con =

    mysql_connect(…); $connected = is_resource($con);
  59. PHP 7.0 “Gotchas” Another bird with the PHP 7.0 stone

    ext/mssql functions instead use sqlsrv_*(), odbc_*(), PDO
  60. PHP 7.0 “Gotchas” A few others for the chopping block

    Some ext/mcrypt functions, et. al.
  61. PHP 7.0 “Gotchas” Scalar Type Declarations New reserved keywords: string,

    int, bool, float
  62. None
  63. PHP 7.0 “Gotchas” Uniform Variable Syntax Change in evaluating indirect

    expressions @SammyK #zendcon2016 joind.in/talk/6d127
  64. PHP 7.0 “Gotchas” Uniform Variable Syntax $$foo['bar']['baz']

  65. PHP 7.0 “Gotchas” Uniform Variable Syntax $foo = ['bar' =>

    ['baz' => ‘apple']]; $apple = 'PHP 5.x I see...'; var_dump($$foo['bar']['baz']); string(16) "PHP 5.x I see..." 5.x
  66. PHP 7.0 “Gotchas” Uniform Variable Syntax Notice: Array to string

    conversion in / foo.php on line 6 Notice: Undefined variable: Array in / foo.php on line 6 7.x
  67. PHP 7.0 “Gotchas” Uniform Variable Syntax $$foo['bar']['baz'] 5.x

  68. PHP 7.0 “Gotchas” Uniform Variable Syntax $$foo['bar']['baz'] 5.x

  69. PHP 7.0 “Gotchas” Uniform Variable Syntax ${'apple'} 5.x

  70. PHP 7.0 “Gotchas” Uniform Variable Syntax $apple 5.x string(16) "PHP

    5.x I see..."
  71. PHP 7.0 “Gotchas” Uniform Variable Syntax $$foo['bar']['baz'] 7.x

  72. PHP 7.0 “Gotchas” Uniform Variable Syntax $$foo['bar']['baz'] 7.x

  73. PHP 7.0 “Gotchas” Uniform Variable Syntax ${['bar' => ['baz' =>

    ‘apple']} [‘bar’]['baz'] 7.x
  74. PHP 7.0 “Gotchas” Uniform Variable Syntax ${‘Array’}[‘bar’]['baz'] 7.x

  75. PHP 7.0 “Gotchas” Uniform Variable Syntax $$foo['bar']['baz'] 7.x

  76. PHP 7.0 “Gotchas” Uniform Variable Syntax ${$foo[‘bar’]['baz']} 7.x

  77. PHP 7.0 “Gotchas” $$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz'] 5.x 7.x Uniform Variable

    Syntax
  78. FOUR Step @SammyK #zendcon2016 joind.in/talk/6d127

  79. Code! @SammyK #zendcon2016 joind.in/talk/6d127

  80. Tests TESTS Tests @SammyK #zendcon2016 joind.in/talk/6d127

  81. PHPUnit? @SammyK #zendcon2016 joind.in/talk/6d127

  82. Acceptance Tests @SammyK #zendcon2016 joind.in/talk/6d127

  83. Codeception @SammyK #zendcon2016 joind.in/talk/6d127

  84. Behavior-driven testing framework @SammyK #zendcon2016 joind.in/talk/6d127

  85. Composer + Autoloading @SammyK #zendcon2016 joind.in/talk/6d127

  86. @SammyK #zendcon2016 joind.in/talk/6d127

  87. Feature (User Story)

  88. Scenario

  89. @SammyK #zendcon2016 joind.in/talk/6d127

  90. Scenario @SammyK #zendcon2016 joind.in/talk/6d127

  91. None
  92. FIVE Step “The Refactoring Loop” @SammyK #zendcon2016 joind.in/talk/6d127

  93. refactorLoop: @SammyK #zendcon2016 joind.in/talk/6d127

  94. Start small @SammyK #zendcon2016 joind.in/talk/6d127

  95. None
  96. Make sure there’s a test @SammyK #zendcon2016 joind.in/talk/6d127

  97. @SammyK #zendcon2016 joind.in/talk/6d127 Refactor

  98. Run your tests @SammyK #zendcon2016 joind.in/talk/6d127

  99. goto refactorLoop; @SammyK #zendcon2016 joind.in/talk/6d127

  100. lets you refactor like a BEAST @SammyK #zendcon2016 joind.in/talk/6d127

  101. PHPUnit Don’t forget about

  102. PHP 7.0 Features @SammyK #zendcon2016 joind.in/talk/6d127

  103. random_int() random_bytes() PHP 7.0 Features CSPRNG!! @SammyK #zendcon2016 joind.in/talk/6d127

  104. JOURNEY MY CENTER TO THE OF #ShamelessPlug Tomorrow @ 11:30am

    in Festival 2
  105. PHP 7.0 Features Scalar Type Declarations @SammyK #zendcon2016 joind.in/talk/6d127

  106. PHP 7.0 Features Scalar Type Declarations function foo(string $name,
 int

    $age,
 bool $isGreat,
 float $income)
 { /* */ }
  107. PHP 7.0 Features Scalar Type Declarations function foo(string $name,
 int

    $age,
 bool $isGreat,
 float $income)
 { /* */ }
  108. 99.99999999999942 I got problems but float $income NEVER USE FLOATS

    FOR MONEY!
  109. PHP 7.0 Features Return type declarations @SammyK #zendcon2016 joind.in/talk/6d127

  110. PHP 7.0 Features Return type declarations /**
 * @return Collection


    */
 public function foo()
 {
 }
  111. PHP 7.0 Features /**
 * @return Collection
 */
 public function

    foo()
 {
 } Return type declarations
  112. PHP 7.0 Features public function foo(): Collection
 {
 } Return

    type declarations
  113. PHP 7.0 Features Null coalesce operator @SammyK #zendcon2016 joind.in/talk/6d127

  114. PHP 7.0 Features $bar = isset($_GET[‘foo’]) ? $_GET[‘foo’] : null;

    Null coalesce operator $bar = $_GET[‘foo’] ?? null;
  115. PHP 7.0 Features Insane speed improvements @SammyK #zendcon2016 joind.in/talk/6d127

  116. And beyond? @SammyK #zendcon2016 joind.in/talk/6d127

  117. PHP 7.1 Considering RC3 @SammyK #zendcon2016 joind.in/talk/6d127

  118. PHP 7.1 considerations deprecated ext/mcrypt Soon to be...

  119. Void return types PHP 7.1 considerations @SammyK #zendcon2016 joind.in/talk/6d127

  120. public function foo(): void
 {
 } Void return types PHP

    7.1 considerations
  121. Nullable types PHP 7.1 considerations @SammyK #zendcon2016 joind.in/talk/6d127 (kinda like

    union types for null)
  122. Nullable types function foo(string $name)
 { /* */ } PHP

    7.1 considerations
  123. Nullable types function foo(?string $name)
 { /* */ } PHP

    7.1 considerations
  124. Nullable types function foo(string $name = null)
 { /* */

    } foo(); PHP 7.1 considerations
  125. Nullable types foo(); function foo(?string $name)
 { /* */ }

    foo(null); PHP 7.1 considerations
  126. Nullable types function foo(): ?string { return null; } PHP

    7.1 considerations
  127. Class constant visibility PHP 7.1 considerations @SammyK #zendcon2016 joind.in/talk/6d127

  128. Class constant visibility class Foo {
 public const FOO =

    0; protected const BAR = 1; private const BAZ = 2; } PHP 7.1 considerations
  129. `iterable` pseudo-type PHP 7.1 considerations @SammyK #zendcon2016 joind.in/talk/6d127

  130. `iterable` pseudo-type function foo(iterable $a)
 { /* */ } PHP

    7.1 considerations $b = []; foo($b); class C implements Iterator {} $b = new C; foo($b);
  131. `iterable` pseudo-type PHP 7.1 considerations class D implements IteratorAggregate {}

    foo(new D); Traversable Or instance of
  132. Some tools I like @SammyK #zendcon2016 joind.in/talk/6d127

  133. vlucas/phpdotenv .env No peeking! No peeking!

  134. Some tools I like pimple/pimple @SammyK #zendcon2016 joind.in/talk/6d127

  135. Some tools I like monolog/monolog @SammyK #zendcon2016 joind.in/talk/6d127

  136. Some tools I like nikic/fast-route @SammyK #zendcon2016 joind.in/talk/6d127

  137. Some tools I like illuminate/database @SammyK #zendcon2016 joind.in/talk/6d127

  138. Some tools I like symfony/console @SammyK #zendcon2016 joind.in/talk/6d127

  139. Create a PHP application without a framework https://github.com/PatrickLouys/no-framework-tutorial Patrick Louys

    @SammyK #zendcon2016 joind.in/talk/6d127
  140. Big-picture Refactoring @SammyK #zendcon2016 joind.in/talk/6d127

  141. Constant refactoring is the key to managing legacy codebases @SammyK

    #zendcon2016 joind.in/talk/6d127
  142. Constant refactoring is the key to managing legacy codebases @SammyK

    #zendcon2016 joind.in/talk/6d127
  143. Resources 013: TDD & BDD In PHP Soon: Acceptance Testing

    with Behat 017: Modernizing Legacy Codebases in PHP November 3rd @ 12:00PM CDT
  144. Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Paul M. Jones @SammyK

    #zendcon2016 joind.in/talk/6d127
  145. Refactoring Martin Fowler http://martinfowler.com/books/refactoring.html @SammyK #zendcon2016 joind.in/talk/6d127

  146. Takk! (thanks) @SammyK SammyK.me Host of @PHPRoundtable @ChiPHPUG West Coast

    Swing Hire me! :) /talk/6d127