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

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

Bringing Old Legacy Apps To PHP 7 and Beyond - Midwest 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

March 17, 2017
Tweet

More Decks by Sammy Kaye Powers

Other Decks in Programming

Transcript

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

    View Slide

  2. Codebase
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  3. View Slide

  4. I’ll just rewrite
    this in
    ____________!
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  5. I’ll just rewrite
    this in
    ____________!
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

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

    View Slide

  7. I’ll just rewrite
    this in
    ____________!
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  8. rewrite from
    scratch?
    Why not
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  9. Functionality
    Existing Codebase Fancy-pants rewrite

    View Slide

  10. Functionality
    Existing Codebase Fancy-pants rewrite

    View Slide

  11. Functionality
    Existing Codebase Fancy-pants rewrite

    View Slide

  12. Functionality
    Existing Codebase Fancy-pants rewrite

    View Slide

  13. Functionality
    Existing Codebase Fancy-pants rewrite

    View Slide

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

    View Slide

  15. “Legacy”
    /leɡəsē/
    • Requires an EOL version of PHP
    • No automated tests
    • Has outdated dependencies
    • No autoloading
    • No sign of “single responsibility”

    View Slide

  16. View Slide

  17. “Legacy”
    We’ll assume
    …means any code that
    can be improved
    (at least for this talk)
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  18. Expectations
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  19. elePHPant
    How to eat an

    View Slide

  20. ZERO
    Step
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  21. Around
    Poke
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  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)

    View Slide

  23. Analysis
    Static
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  24. phploc

    View Slide

  25. phploc

    View Slide

  26. phpcpd

    View Slide

  27. Consider the
    Stakeholders
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  28. Consider the Stakeholders
    I’ll need 80
    hours to
    refactor the
    user auth & ACL
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  29. Consider the Stakeholders
    • Most critical security holes
    • Most critical bugs
    • Most critical features
    • Use data from static analysis
    Make a plan

    View Slide

  30. ONE
    Step
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  31. 5.(wat)
    @SammyK #mwphp17 joind.in/talk/82979
    Get it running on

    View Slide

  32. Environment
    Get it running on your local
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  33. Kickass
    Development
    Environments
    with Docker
    David McKay
    Tomorrow @ 11 AM in Ballroom D
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  34. Git with an
    SCM

    View Slide

  35. View Slide

  36. Git
    Get with
    master
    original
    local-config

    View Slide

  37. Fix all the errors
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  38. View Slide

  39. TWO
    Step
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  40. 7.1
    @SammyK #mwphp17 joind.in/talk/82979
    Get it running on

    View Slide

  41. 7.1
    ✓Performance
    increase
    PHP 7
    features

    View Slide

  42. 7.1

    View Slide

  43. BC
    is totes amaze

    View Slide

  44. PHP 7 enlightenment
    The path to
    7.1
    5.6

    View Slide

  45. 7.1
    5.5
    PHP 7 enlightenment
    The path to

    View Slide

  46. 7.1
    5.4
    PHP 7 enlightenment
    The path to

    View Slide

  47. 7.1
    >= 5.3
    PHP 7 enlightenment
    The path to

    View Slide

  48. THREE
    Step
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  49. Fix all the PHP 7 errors
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  50. PHP 7
    Quick tricks to refactor to
    (in order of ease)
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  51. PHP 7.0 “Gotchas”
    ASP and
    PHP<br/>tags removed<br/>@SammyK #mwphp17 joind.in/talk/82979<br/>

    View Slide

  52. <% %>
    <%= %>
    <br/>
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  53. PHP 7.0 “Gotchas”
    removed
    $HTTP_RAW_POST_DATA
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  54. php://input
    instead read from
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  55. PHP 7.0 “Gotchas”
    PHP-4-style
    constructors
    deprecated
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  56. View Slide

  57. View Slide

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

    View Slide

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

    View Slide

  60. PHP 7.0 “Gotchas”
    “There’s a shim for that!”
    ereg* functions
    bbrala/php7-ereg-shim
    (Björn Brala)

    View Slide

  61. View Slide

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

    View Slide

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

    View Slide

  64. Caveats though…

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  68. View Slide

  69. PHP 7.0 “Gotchas”
    Uniform
    Variable Syntax
    Change in evaluating indirect expressions
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  70. View Slide

  71. Variable variables
    string(5) "world"

    View Slide

  72. View Slide

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

    View Slide

  74. 7.x

    View Slide

  75. View Slide

  76. 5.x

    View Slide

  77. 5.x

    View Slide

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

    View Slide

  79. 7.x

    View Slide

  80. 7.x

    View Slide

  81. 7.x

    View Slide

  82. 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

  83. Funky

    View Slide

  84. View Slide

  85. View Slide

  86. 7.x
    5.x

    View Slide

  87. FOUR
    Step
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  88. Code!
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  89. Tests
    TESTS
    Tests
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  90. PHPUnit?
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  91. Acceptance
    Tests
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  92. Codeception
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  93. Behavior-driven
    testing framework
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  94. Composer +
    Autoloading
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  95. @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  96. Feature
    (User Story)

    View Slide

  97. Scenario

    View Slide

  98. @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  99. Scenario
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  100. View Slide

  101. FIVE
    Step
    “The Refactoring Loop”
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  102. refactorLoop:
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  103. Start
    small
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  104. View Slide

  105. Make sure there’s a test
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  106. Refactor
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  107. Run your tests
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  108. goto refactorLoop;
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  109. lets you refactor like a
    BEAST
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  110. PHPUnit
    Don’t forget about

    View Slide

  111. PHP 7.0
    Features
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  112. random_int()
    random_bytes()
    PHP 7.0 Features
    CSPRNG!!
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  113. JOURNEY
    MY
    CENTER
    TO
    THE
    OF
    #ShamelessPlug
    Tomorrow @ 10 am
    in Main Ballroom

    View Slide

  114. PHP 7.0 Features
    Scalar Type
    Declarations
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

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

    int $age,

    bool $isGreat,

    float $income)

    { /* */ }

    View Slide

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

    int $age,

    bool $isGreat,

    float $income)

    { /* */ }

    View Slide

  117. PHP 7.0 Features
    Return type
    declarations
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  118. PHP 7.0 Features
    Return type declarations
    /**

    * @return Collection

    */

    public function foo()

    {

    }

    View Slide

  119. PHP 7.0 Features
    /**

    * @return Collection

    */

    public function foo()

    {

    }
    Return type declarations

    View Slide

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

    {

    }
    Return type declarations

    View Slide

  121. PHP 7.0 Features
    Null coalesce
    operator
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

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

    View Slide

  123. PHP 7.0 Features
    Insane speed
    improvements
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  124. PHP 7.1
    Considerations & Features
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  125. PHP 7.1 Considerations
    deprecated
    ext/mcrypt
    Soon to be...

    View Slide

  126. rand() &
    mt_rand()
    changes
    PHP 7.1 Considerations

    View Slide

  127. View Slide

  128. Totes Samezies!

    View Slide

  129. array_rand()
    Now with even distribution!
    PHP 7.1 Considerations

    View Slide

  130. Void return
    types
    PHP 7.1 Features
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  131. public function foo(): void

    {

    }
    Void return types
    PHP 7.1 Features

    View Slide

  132. Nullable
    types
    (kinda like union types for null)
    @SammyK #mwphp17 joind.in/talk/82979
    PHP 7.1 Features

    View Slide

  133. Nullable types
    function foo(string $name)

    { /* */ }
    PHP 7.1 Features

    View Slide

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

    { /* */ }
    PHP 7.1 Features

    View Slide

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

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

    View Slide

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

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

    View Slide

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

    View Slide

  138. Class constant
    visibility
    @SammyK #mwphp17 joind.in/talk/82979
    PHP 7.1 Features

    View Slide

  139. Class constant visibility
    class Foo {

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

    View Slide

  140. `iterable`
    pseudo-type
    @SammyK #mwphp17 joind.in/talk/82979
    PHP 7.1 Features

    View Slide

  141. `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

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

    View Slide

  143. And
    beyond?
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  144. PHP 7.2
    Considering
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

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

    View Slide

  146. PHP 7.2 considerations
    Argon2
    Password Hash
    password_*()
    (Could become new default in PHP 7.3/8.0)

    View Slide

  147. Pending implementation…
    PHP 7.2

    View Slide

  148. PHP 7.2 considerations
    sodium_*()

    View Slide

  149. PHP 7.2 considerations
    Trailing Comma

    View Slide

  150. 7.2 Deprecations
    (Will be removed by PHP 8.0)

    View Slide

  151. Some tools
    I like
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

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

    View Slide

  153. Some tools I like
    pimple/pimple
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  154. Some tools I like
    monolog/monolog
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  155. Some tools I like
    nikic/fast-route
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  156. Some tools I like
    illuminate/database
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  157. Some tools I like
    symfony/console
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  158. Create a PHP
    application without a
    framework
    https://github.com/PatrickLouys/no-framework-tutorial
    Patrick Louys
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  159. Big-picture
    Refactoring
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  160. Constant refactoring
    is the key to managing
    legacy
    codebases
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  161. Constant refactoring
    is the key to managing
    legacy
    codebases
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  162. Resources
    013: TDD & BDD In PHP
    055: Acceptance
    Testing with Behat
    017: Modernizing Legacy
    Codebases in PHP
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  163. Modernizing Legacy
    Applications in PHP
    https://leanpub.com/mlaphp
    Paul M. Jones
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  164. Refactoring
    Martin Fowler
    http://martinfowler.com/books/refactoring.html
    @SammyK #mwphp17 joind.in/talk/82979

    View Slide

  165. Takk!
    (thanks)
    @SammyK
    SammyK.me
    Host of @PHPRoundtable
    @ChiPHPUG
    West Coast Swing
    Hire me! :)
    /talk/82979

    View Slide