Bringing Old Legacy Apps To PHP 7 and Beyond - PNWPHP 2017

Bringing Old Legacy Apps To PHP 7 and Beyond - PNWPHP 2017

Talk given at Pacific Northwest PHP 2017

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 written years ago for an end-of-life version of PHP and a now-defunct web framework. The initial temptation might be, "I'll just rewrite all this on x framework". But hold on there my framework friend, a rewrite is costly and is rarely the correct answer. We'll discuss some common pitfalls when getting a legacy codebase ready for PHP 7 and what we can do to make the upgrade path as painless as possible. These incremental changes will keep the business running while improving security, stability and maintainability of the codebase.

8c090cc1ccd623a146ddd9159b1bf7e2?s=128

Sammy Kaye Powers

September 09, 2017
Tweet

Transcript

  1. Bringing Old Legacy Apps To September 9th, 2017 Sammy Kaye

    Powers @SammyK PHP 7 & Beyond
  2. joind.in/talk/228f1 @SammyK #pnwphp Slides Get the joind.in/talk/228f1

  3. joind.in/talk/228f1 @SammyK #pnwphp Upgrade Path 7.1 Less about More about

    Refactoring Strategies to
  4. joind.in/talk/228f1 @SammyK #pnwphp Codebase

  5. joind.in/talk/228f1 @SammyK #pnwphp

  6. joind.in/talk/228f1 @SammyK #pnwphp I’ll just rewrite this in ____________!

  7. joind.in/talk/228f1 @SammyK #pnwphp I’ll just rewrite this in ____________!

  8. joind.in/talk/228f1 @SammyK #pnwphp I’ll just rewrite this in ____________! Laravel

  9. joind.in/talk/228f1 @SammyK #pnwphp I’ll just rewrite this in ____________!

  10. joind.in/talk/228f1 @SammyK #pnwphp rewrite from scratch? Why not

  11. joind.in/talk/228f1 @SammyK #pnwphp Functionality Existing Codebase Fancy-pants rewrite

  12. joind.in/talk/228f1 @SammyK #pnwphp Functionality Existing Codebase Fancy-pants rewrite

  13. joind.in/talk/228f1 @SammyK #pnwphp Functionality Existing Codebase Fancy-pants rewrite

  14. joind.in/talk/228f1 @SammyK #pnwphp Functionality Existing Codebase Fancy-pants rewrite

  15. joind.in/talk/228f1 @SammyK #pnwphp Functionality Existing Codebase Fancy-pants rewrite

  16. joind.in/talk/228f1 @SammyK #pnwphp Refactoring Martin Fowler http://martinfowler.com/books/refactoring.html

  17. joind.in/talk/228f1 @SammyK #pnwphp “Legacy” /leɡəsē/ • Requires an EOL version

    of PHP • No automated tests • Has outdated dependencies • No autoloading • No sign of “single responsibility”
  18. joind.in/talk/228f1 @SammyK #pnwphp

  19. joind.in/talk/228f1 @SammyK #pnwphp “Legacy” We’ll assume …means any code that

    is running on PHP 5.x (at least for this talk)
  20. joind.in/talk/228f1 @SammyK #pnwphp Expectations

  21. joind.in/talk/228f1 @SammyK #pnwphp elePHPant How to eat an

  22. joind.in/talk/228f1 @SammyK #pnwphp ZERO Step

  23. joind.in/talk/228f1 @SammyK #pnwphp Around Poke

  24. joind.in/talk/228f1 @SammyK #pnwphp 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)
  25. joind.in/talk/228f1 @SammyK #pnwphp Analysis Static

  26. phploc

  27. phploc

  28. phpcpd

  29. joind.in/talk/228f1 @SammyK #pnwphp Consider the Stakeholders

  30. joind.in/talk/228f1 @SammyK #pnwphp Consider the Stakeholders I’ll need 80 hours

    to refactor the user auth & ACL
  31. joind.in/talk/228f1 @SammyK #pnwphp Consider the Stakeholders • Most critical security

    holes • Most critical bugs • Most critical features • Use data from static analysis Make a plan
  32. joind.in/talk/228f1 @SammyK #pnwphp ONE Step

  33. joind.in/talk/228f1 @SammyK #pnwphp 5.(wat) Get it running on

  34. Environment Get it running on your local

  35. joind.in/talk/228f1 @SammyK #pnwphp Git with an SCM

  36. joind.in/talk/228f1 @SammyK #pnwphp

  37. joind.in/talk/228f1 @SammyK #pnwphp Git Get with master original local-config

  38. joind.in/talk/228f1 @SammyK #pnwphp Fix all the errors

  39. None
  40. joind.in/talk/228f1 @SammyK #pnwphp TWO Step

  41. joind.in/talk/228f1 @SammyK #pnwphp 7.1 Get it running on

  42. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 Is almost 2 years old!

  43. joind.in/talk/228f1 @SammyK #pnwphp 2

  44. joind.in/talk/228f1 @SammyK #pnwphp years

  45. joind.in/talk/228f1 @SammyK #pnwphp old!

  46. joind.in/talk/228f1 @SammyK #pnwphp OLD

  47. joind.in/talk/228f1 @SammyK #pnwphp http://php.net/supported-versions.php > 3 months Active support (bug

    fixes) for PHP 7.0 ends
  48. joind.in/talk/228f1 @SammyK #pnwphp OLD PHP 7.0 is

  49. 7.1 ✓Performance increase PHP 7 features ✓

  50. 7.1

  51. BC is totes amaze

  52. joind.in/talk/228f1 @SammyK #pnwphp PHP 7 enlightenment The path to 7.1

    5.6
  53. joind.in/talk/228f1 @SammyK #pnwphp 7.1 5.5 PHP 7 enlightenment The path

    to
  54. joind.in/talk/228f1 @SammyK #pnwphp 7.1 5.4 PHP 7 enlightenment The path

    to
  55. joind.in/talk/228f1 @SammyK #pnwphp 7.1 <= 5.3 PHP 7 enlightenment The

    path to
  56. joind.in/talk/228f1 @SammyK #pnwphp THREE Step

  57. joind.in/talk/228f1 @SammyK #pnwphp Fix all the PHP 7 errors

  58. joind.in/talk/228f1 @SammyK #pnwphp PHP 7 Quick tricks to refactor to

    (in order of ease)
  59. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 “Gotchas” ASP and <script> PHP

    tags removed
  60. <% %> <%= %> <script language=“php"> </script>

  61. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 “Gotchas” removed $HTTP_RAW_POST_DATA

  62. joind.in/talk/228f1 @SammyK #pnwphp php://input instead read from

  63. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 “Gotchas” PHP-4-style constructors deprecated

  64. joind.in/talk/228f1 @SammyK #pnwphp

  65. joind.in/talk/228f1 @SammyK #pnwphp

  66. PHP 7.0 “Gotchas” Some functions got the ax ereg* functions

  67. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 “Gotchas” “There’s a shim for

    that!”
  68. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 “Gotchas” “There’s a shim for

    that!” ereg* functions bbrala/php7-ereg-shim (Björn Brala)
  69. joind.in/talk/228f1 @SammyK #pnwphp

  70. PHP 7.0 “Gotchas” Another one bites the dust ext/mysql functions

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

    dshafik/php7-mysql-shim (Davey Shafik)
  72. joind.in/talk/228f1 @SammyK #pnwphp Caveats though…

  73. PHP 7.0 “Gotchas” Another bird with the PHP 7.0 stone

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

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

    int, bool, float
  76. None
  77. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 “Gotchas” Uniform Variable Syntax Change

    in evaluating indirect expressions
  78. joind.in/talk/228f1 @SammyK #pnwphp

  79. Variable variables string(5) "world"

  80. joind.in/talk/228f1 @SammyK #pnwphp

  81. string(16) "PHP 5.x I see..." 5.x

  82. 7.x

  83. joind.in/talk/228f1 @SammyK #pnwphp

  84. joind.in/talk/228f1 @SammyK #pnwphp 5.x

  85. joind.in/talk/228f1 @SammyK #pnwphp 5.x

  86. joind.in/talk/228f1 @SammyK #pnwphp 5.x string(16) "PHP 5.x I see..."

  87. joind.in/talk/228f1 @SammyK #pnwphp 7.x

  88. joind.in/talk/228f1 @SammyK #pnwphp 7.x

  89. joind.in/talk/228f1 @SammyK #pnwphp 7.x

  90. joind.in/talk/228f1 @SammyK #pnwphp 7.x Notice: Array to string conversion in

    / foo.php on line 6 Notice: Undefined variable: Array in / foo.php on line 6
  91. joind.in/talk/228f1 @SammyK #pnwphp Funky

  92. joind.in/talk/228f1 @SammyK #pnwphp

  93. None
  94. joind.in/talk/228f1 @SammyK #pnwphp 7.x 5.x

  95. joind.in/talk/228f1 @SammyK #pnwphp FOUR Step

  96. joind.in/talk/228f1 @SammyK #pnwphp Code!

  97. joind.in/talk/228f1 @SammyK #pnwphp Tests TESTS Tests

  98. joind.in/talk/228f1 @SammyK #pnwphp PHPUnit?

  99. joind.in/talk/228f1 @SammyK #pnwphp Acceptance Tests

  100. joind.in/talk/228f1 @SammyK #pnwphp Codeception

  101. joind.in/talk/228f1 @SammyK #pnwphp Behavior-driven testing framework

  102. joind.in/talk/228f1 @SammyK #pnwphp Composer + Autoloading

  103. joind.in/talk/228f1 @SammyK #pnwphp

  104. Feature (User Story)

  105. joind.in/talk/228f1 @SammyK #pnwphp Scenario

  106. joind.in/talk/228f1 @SammyK #pnwphp

  107. joind.in/talk/228f1 @SammyK #pnwphp Scenario

  108. None
  109. joind.in/talk/228f1 @SammyK #pnwphp FIVE Step “The Refactoring Loop”

  110. joind.in/talk/228f1 @SammyK #pnwphp refactorLoop:

  111. joind.in/talk/228f1 @SammyK #pnwphp Start small

  112. None
  113. joind.in/talk/228f1 @SammyK #pnwphp Make sure there’s a test

  114. joind.in/talk/228f1 @SammyK #pnwphp Refactor

  115. joind.in/talk/228f1 @SammyK #pnwphp Run your tests

  116. joind.in/talk/228f1 @SammyK #pnwphp goto refactorLoop;

  117. joind.in/talk/228f1 @SammyK #pnwphp lets you refactor like a BEAST

  118. PHPUnit Don’t forget about

  119. joind.in/talk/228f1 @SammyK #pnwphp End-to-end is great! Except when…

  120. joind.in/talk/228f1 @SammyK #pnwphp It’s Not

  121. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 Features

  122. joind.in/talk/228f1 @SammyK #pnwphp random_int() random_bytes() PHP 7.0 Features CSPRNG!!

  123. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 Features Scalar Type Declarations

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

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

    $age,
 bool $isGreat,
 float $income)
 { /* */ }
  126. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 Features Return type declarations

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


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

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

    type declarations
  130. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 Features Null coalesce operator

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

    Null coalesce operator $bar = $_GET[‘foo’] ?? null;
  132. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.0 Features Insane speed improvements

  133. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.1 Considerations & Features

  134. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.1 Considerations deprecated ext/mcrypt Soon to

    be...
  135. joind.in/talk/228f1 @SammyK #pnwphp rand() & mt_rand() changes PHP 7.1 Considerations

  136. joind.in/talk/228f1 @SammyK #pnwphp

  137. joind.in/talk/228f1 @SammyK #pnwphp Totes Samezies!

  138. joind.in/talk/228f1 @SammyK #pnwphp array_rand() Now with even distribution! PHP 7.1

    Considerations
  139. joind.in/talk/228f1 @SammyK #pnwphp Void return types PHP 7.1 Features

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

    7.1 Features
  141. joind.in/talk/228f1 @SammyK #pnwphp Nullable types (kinda like union types for

    null) PHP 7.1 Features
  142. Nullable types function foo(string $name)
 { /* */ } PHP

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

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

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

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

    7.1 Features
  147. joind.in/talk/228f1 @SammyK #pnwphp Class constant visibility PHP 7.1 Features

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

    0; protected const BAR = 1; private const BAZ = 2; } PHP 7.1 Features
  149. joind.in/talk/228f1 @SammyK #pnwphp `iterable` pseudo-type PHP 7.1 Features

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

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

    Or instance of PHP 7.1 Features
  152. joind.in/talk/228f1 @SammyK #pnwphp And beyond?

  153. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 Considering

  154. PHP 7.2 considerations re(moved) ext/mcrypt

  155. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations Argon2 Password Hash password_*()

    (Could become new default in PHP 7.3/8.0)
  156. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations sodium_*()

  157. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations Trailing Comma

  158. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations Undefined Constants

  159. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations

  160. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations

  161. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations Type Annotation object

  162. joind.in/talk/228f1 @SammyK #pnwphp PHP 7.2 considerations

  163. joind.in/talk/228f1 @SammyK #pnwphp 7.2 Deprecations (Will be removed by PHP

    8.0)
  164. joind.in/talk/228f1 @SammyK #pnwphp Some tools I like

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

  166. vlucas/phpdotenv NotSecure :(

  167. Env vars aren’t designed for secrets (shared with child processes,

    etc) Error messages can contain dump of env vars (filp/whoops)
  168. joind.in/talk/228f1 @SammyK #pnwphp Some tools I like pimple/pimple

  169. joind.in/talk/228f1 @SammyK #pnwphp Some tools I like monolog/monolog

  170. joind.in/talk/228f1 @SammyK #pnwphp Some tools I like nikic/fast-route

  171. joind.in/talk/228f1 @SammyK #pnwphp Some tools I like illuminate/database

  172. joind.in/talk/228f1 @SammyK #pnwphp Some tools I like symfony/console

  173. joind.in/talk/228f1 @SammyK #pnwphp Create a PHP application without a framework

    https://github.com/PatrickLouys/no-framework-tutorial Patrick Louys
  174. joind.in/talk/228f1 @SammyK #pnwphp Big-picture Refactoring

  175. joind.in/talk/228f1 @SammyK #pnwphp Constant refactoring is the key to managing

    legacy codebases
  176. joind.in/talk/228f1 @SammyK #pnwphp Constant refactoring is the key to managing

    legacy codebases
  177. joind.in/talk/228f1 @SammyK #pnwphp Resources 013: TDD & BDD In PHP

    055: Acceptance Testing with Behat 017: Modernizing Legacy Codebases in PHP
  178. joind.in/talk/228f1 @SammyK #pnwphp Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Paul

    M. Jones
  179. joind.in/talk/228f1 @SammyK #pnwphp Refactoring Martin Fowler http://martinfowler.com/books/refactoring.html

  180. I have stickers! Takk! (thanks) @SammyK SammyK.me Host of @PHPRoundtable

    @ChiPHPUG West Coast Swing /talk/228f1