$30 off During Our Annual Pro Sale. View Details »

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.

Sammy Kaye Powers

September 09, 2017
Tweet

More Decks by Sammy Kaye Powers

Other Decks in Programming

Transcript

  1. Bringing Old Legacy Apps To
    September 9th, 2017
    Sammy Kaye Powers
    @SammyK
    PHP 7 & Beyond

    View Slide

  2. joind.in/talk/228f1
    @SammyK #pnwphp
    Slides
    Get the
    joind.in/talk/228f1

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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”

    View Slide

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

    View Slide

  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)

    View Slide

  20. joind.in/talk/228f1
    @SammyK #pnwphp
    Expectations

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  25. joind.in/talk/228f1
    @SammyK #pnwphp
    Analysis
    Static

    View Slide

  26. phploc

    View Slide

  27. phploc

    View Slide

  28. phpcpd

    View Slide

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

    View Slide

  30. joind.in/talk/228f1
    @SammyK #pnwphp
    Consider the Stakeholders
    I’ll need 80
    hours to
    refactor the
    user auth & ACL

    View Slide

  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

    View Slide

  32. joind.in/talk/228f1
    @SammyK #pnwphp
    ONE
    Step

    View Slide

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

    View Slide

  34. Environment
    Get it running on your local

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  39. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. 7.1
    ✓Performance
    increase
    PHP 7
    features

    View Slide

  50. 7.1

    View Slide

  51. BC
    is totes amaze

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  58. joind.in/talk/228f1
    @SammyK #pnwphp
    PHP 7
    Quick tricks to refactor to
    (in order of ease)

    View Slide

  59. joind.in/talk/228f1
    @SammyK #pnwphp
    PHP 7.0 “Gotchas”
    ASP and
    PHP<br/>tags removed<br/>

    View Slide

  60. <% %>
    <%= %>
    <br/>

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

  71. PHP 7.0 “Gotchas”
    “There’s a shim for that!”
    ext/mysql functions
    dshafik/php7-mysql-shim
    (Davey Shafik)

    View Slide

  72. joind.in/talk/228f1
    @SammyK #pnwphp
    Caveats though…

    View Slide

  73. PHP 7.0 “Gotchas”
    Another bird
    with the
    PHP 7.0 stone
    ext/mssql
    functions
    instead use
    sqlsrv_*(), odbc_*(), PDO

    View Slide

  74. PHP 7.0 “Gotchas”
    A few others
    for the
    chopping
    block
    Some
    ext/mcrypt
    functions,
    et. al.

    View Slide

  75. PHP 7.0 “Gotchas”
    Scalar Type
    Declarations
    New reserved keywords:
    string, int, bool, float

    View Slide

  76. View Slide

  77. joind.in/talk/228f1
    @SammyK #pnwphp
    PHP 7.0 “Gotchas”
    Uniform
    Variable Syntax
    Change in evaluating indirect expressions

    View Slide

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

    View Slide

  79. Variable variables
    string(5) "world"

    View Slide

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

    View Slide

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

    View Slide

  82. 7.x

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  91. joind.in/talk/228f1
    @SammyK #pnwphp
    Funky

    View Slide

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

    View Slide

  93. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  104. Feature
    (User Story)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  108. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  112. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  118. PHPUnit
    Don’t forget about

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    int $age,

    bool $isGreat,

    float $income)

    { /* */ }

    View Slide

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

    int $age,

    bool $isGreat,

    float $income)

    { /* */ }

    View Slide

  126. joind.in/talk/228f1
    @SammyK #pnwphp
    PHP 7.0 Features
    Return type
    declarations

    View Slide

  127. PHP 7.0 Features
    Return type declarations
    /**

    * @return Collection

    */

    public function foo()

    {

    }

    View Slide

  128. PHP 7.0 Features
    /**

    * @return Collection

    */

    public function foo()

    {

    }
    Return type declarations

    View Slide

  129. PHP 7.0 Features
    public function foo(): Collection

    {

    }
    Return type declarations

    View Slide

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

    View Slide

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

    View Slide

  132. joind.in/talk/228f1
    @SammyK #pnwphp
    PHP 7.0 Features
    Insane speed
    improvements

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  140. public function foo(): void

    {

    }
    Void return types
    PHP 7.1 Features

    View Slide

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

    View Slide

  142. Nullable types
    function foo(string $name)

    { /* */ }
    PHP 7.1 Features

    View Slide

  143. Nullable types
    function foo(?string $name)

    { /* */ }
    PHP 7.1 Features

    View Slide

  144. Nullable types
    function foo(string $name = null)

    { /* */ }
    foo();
    PHP 7.1 Features

    View Slide

  145. Nullable types
    foo();
    function foo(?string $name)

    { /* */ }
    foo(null);
    PHP 7.1 Features

    View Slide

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

    View Slide

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

    View Slide

  148. Class constant visibility
    class Foo {

    public const FOO = 0;
    protected const BAR = 1;
    private const BAZ = 2;
    }
    PHP 7.1 Features

    View Slide

  149. joind.in/talk/228f1
    @SammyK #pnwphp
    `iterable`
    pseudo-type
    PHP 7.1 Features

    View Slide

  150. `iterable` pseudo-type
    function foo(iterable $a)

    { /* */ }
    $b = [];
    foo($b);
    class C implements Iterator {}
    $b = new C;
    foo($b);
    PHP 7.1 Features

    View Slide

  151. `iterable` pseudo-type
    class D implements IteratorAggregate {}
    foo(new D);
    Traversable
    Or instance of
    PHP 7.1 Features

    View Slide

  152. joind.in/talk/228f1
    @SammyK #pnwphp
    And
    beyond?

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  156. joind.in/talk/228f1
    @SammyK #pnwphp
    PHP 7.2 considerations
    sodium_*()

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  166. vlucas/phpdotenv
    NotSecure :(

    View Slide

  167. Env vars aren’t designed for secrets
    (shared with child processes, etc)
    Error messages can contain dump
    of env vars (filp/whoops)

    View Slide

  168. joind.in/talk/228f1
    @SammyK #pnwphp
    Some tools I like
    pimple/pimple

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  173. joind.in/talk/228f1
    @SammyK #pnwphp
    Create a PHP
    application without a
    framework
    https://github.com/PatrickLouys/no-framework-tutorial
    Patrick Louys

    View Slide

  174. joind.in/talk/228f1
    @SammyK #pnwphp
    Big-picture
    Refactoring

    View Slide

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

    View Slide

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

    View Slide

  177. joind.in/talk/228f1
    @SammyK #pnwphp
    Resources
    013: TDD & BDD In PHP
    055: Acceptance
    Testing with Behat
    017: Modernizing Legacy
    Codebases in PHP

    View Slide

  178. joind.in/talk/228f1
    @SammyK #pnwphp
    Modernizing Legacy
    Applications in PHP
    https://leanpub.com/mlaphp
    Paul M. Jones

    View Slide

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

    View Slide

  180. I have
    stickers!
    Takk!
    (thanks)
    @SammyK
    SammyK.me
    Host of @PHPRoundtable
    @ChiPHPUG
    West Coast Swing
    /talk/228f1

    View Slide