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

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.

Sammy Kaye Powers

October 19, 2016
Tweet

More Decks by Sammy Kaye Powers

Other Decks in Programming

Transcript

  1. Bringing Old Legacy Apps To
    October 19th, 2016
    Sammy Kaye Powers
    @SammyK
    PHP 7 & Beyond

    View Slide

  2. Codebase
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

  3. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    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
    @SammyK #zendcon2016 joind.in/talk/6d127
    (at least for this talk)

    View Slide

  18. Expectations
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

  19. elePHPant
    How to eat an

    View Slide

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

    View Slide

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

    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 #zendcon2016 joind.in/talk/6d127

    View Slide

  24. phploc

    View Slide

  25. phploc

    View Slide

  26. phpcpd

    View Slide

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

    View Slide

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

    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 #zendcon2016 joind.in/talk/6d127

    View Slide

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

    View Slide

  32. From Docker to
    production
    Chris Tankersley
    @SammyK #zendcon2016 joind.in/talk/6d127
    Today @ 5:15PM in Artist 3

    View Slide

  33. Git
    Get with
    master
    original
    local-config

    View Slide

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

    View Slide

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

    View Slide

  36. View Slide

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

    View Slide

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

    View Slide

  39. 7.0
    ✓Performance
    increase
    PHP 7
    features

    View Slide

  40. 7.0

    View Slide

  41. BC
    is totes amaze

    View Slide

  42. PHP 7.0 enlightenment
    The path to
    7.0
    5.6

    View Slide

  43. PHP 7.0 enlightenment
    The path to
    7.0
    5.5

    View Slide

  44. PHP 7.0 enlightenment
    The path to
    7.0
    5.4

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  48. PHP 7.0
    Quick tricks to refactor to
    (in order of ease)
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

  49. PHP 7.0 “Gotchas”
    ASP and script PHP
    tags removed
    <% %>
    <%= %>

    View Slide

  50. PHP 7.0 “Gotchas”
    removed
    php://input
    $HTTP_RAW_POST_DATA
    instead read from
    $HTTP_RAW_POST_DATA =
    file_get_contents('php://input');

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

  58. PHP 7.0 “Gotchas”
    Caveats though…
    ext/mysql functions
    dshafik/php7-mysql-shim
    $con = mysql_connect(…);
    $connected = is_resource($con);

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  62. View Slide

  63. PHP 7.0 “Gotchas”
    Uniform
    Variable Syntax
    Change in evaluating indirect expressions
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  87. Feature
    (User Story)

    View Slide

  88. Scenario

    View Slide

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

    View Slide

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

    View Slide

  91. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  95. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  101. PHPUnit
    Don’t forget about

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    int $age,

    bool $isGreat,

    float $income)

    { /* */ }

    View Slide

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

    int $age,

    bool $isGreat,

    float $income)

    { /* */ }

    View Slide

  108. 99.99999999999942
    I got
    problems but
    float $income
    NEVER USE
    FLOATS
    FOR MONEY!

    View Slide

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

    View Slide

  110. PHP 7.0 Features
    Return type declarations
    /**

    * @return Collection

    */

    public function foo()

    {

    }

    View Slide

  111. PHP 7.0 Features
    /**

    * @return Collection

    */

    public function foo()

    {

    }
    Return type declarations

    View Slide

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

    {

    }
    Return type declarations

    View Slide

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

    View Slide

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

    View Slide

  115. PHP 7.0 Features
    Insane speed
    improvements
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  120. public function foo(): void

    {

    }
    Void return types
    PHP 7.1 considerations

    View Slide

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

    View Slide

  122. Nullable types
    function foo(string $name)

    { /* */ }
    PHP 7.1 considerations

    View Slide

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

    { /* */ }
    PHP 7.1 considerations

    View Slide

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

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

    View Slide

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

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

    View Slide

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

    View Slide

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

    View Slide

  128. Class constant visibility
    class Foo {

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

    View Slide

  129. `iterable`
    pseudo-type
    PHP 7.1 considerations
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

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

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  139. Create a PHP
    application without a
    framework
    https://github.com/PatrickLouys/no-framework-tutorial
    Patrick Louys
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  143. Resources
    013: TDD & BDD In PHP
    Soon: Acceptance
    Testing with Behat
    017: Modernizing Legacy
    Codebases in PHP
    November 3rd @ 12:00PM CDT

    View Slide

  144. Modernizing Legacy
    Applications in PHP
    https://leanpub.com/mlaphp
    Paul M. Jones
    @SammyK #zendcon2016 joind.in/talk/6d127

    View Slide

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

    View Slide

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

    View Slide