The PHP podcast where everyone chimes in.

Originally aired on

April 15th, 2015

017: Modernizing Legacy Codebases in PHP

We discuss practical ways of dealing with legacy codebases and address the question of, "to rewrite or to refactor"? We also talk about how we should manage client expectations when working with a legacy codebase. And finally we discuss some general strategies for refactoring a codebase to good, clean, modern PHP.

with


How To Convert A Legacy Codebase To Modern PHP Show Summary


What is legacy code?

  • Any code that doesn't have tests
  • Code you have inherited from someone else
  • Code you wrote yourself several years ago
  • In PHP Specifically:
    • Include-oriented/page-based (as opposed to object-oriented and front-controlled)
    • No separation of concerns
    • Everything sits in your webroot
    • Multiple rewrite/refactor attempts are obvious

What is technical debt?

  • It is like taking out a loan - you cut some corners to get the feature now, but cutting those corners makes it harder to change things later
  • "The things that you didn't do that you should have done"
  • Technical debt results in duplication of code, or the same thing stored in more than one place
  • To fix one thing, you need to make a series of co-ordinated changes across the codebase

What do we need to think about before modernizing a legacy codebase?

  • Separation of concerns
  • Understand the business case for the application and determine some acceptance tests
  • High-level integration Tests - if you want to refactor, they'll help to ensure the correct functionality is maintained while changing the implementation details

How do we deal with 'developer ego'?

  • Be suspicious of your own developer ego
  • Get a second opinion - consult with others
  • Look at your own code from one year ago
  • Get others to review your code
  • Use tools like Code Climate or Scrutinizer CI

Are there any currently-used frameworks that we should consider 'legacy'?

  • Version 1 of most frameworks could be considered 'legacy' today, but for different reasons to those discussed so far:
    • Best-practices have changed and moved on
    • PHP itself has changed, particularly with respect to object-orientation
    • Early versions of Zend and Symnfony use singletons extensively

How do we manage a client's expectations when dealing with legacy codebases?

  • It is a difficult thing to communicate
  • Don't make estimates without looking at the codebase - this is no different from working with any unknown codebase
  • In some cases, a client will know they have legacy code because they will be used to code changes taking a long time
  • Charge for a 'discovery' process

What tools can we use to evaluate code/technical debt?

Rewrite vs refactor?

  • Paul and Franziska agree: Always refactor, never rewrite. Just ask Netscape
  • Rewriting sounds like a good idea, but it will always take longer
  • It will be easier to keep evolving a product as you refactor than as you rewrite
  • Hugo's opinion on the rewrite is a bit more sympathetic - if you do rewrite:
    • Once you start the rewrite, don't touch the legacy codebase
    • Re-implement one feature at a time
    • Use some kind of 'switch' (mod_rewrite rules, a load balancer, etc) to run both systems in parallel
    • Dispatch some requests from the legacy system and some from the new codebase
    • As you rewrite and move more features over, dispatch more requests from the new codebase
    • This can be difficult if you need to share info like session variables

How do the panel approach modernizing a legacy codebase?

Paul mentions his book. The first few steps in his process are:

  1. Write integration/characterization tests
  2. Set up autoloading
  3. Consolidate functions and classes so they use the autoloading
  4. Remove globals
  5. Move to using dependency injection
  6. Write unit tests...

He also brings up Michael Feathers - Working Effectively with Legacy Code.

There are tools that can help:

  • XDebug - useful for examining code + working out execution path
  • ACK - useful for finding all the occurrences of particular code/calls
  • PHPStorm
  • phpcpd

Paul Jones

  • Has been working with PHP since 1999, and in that time has been everything from a junior developer to a VP of engineering.
  • Modernizing Legacy Applications in PHP is a step-by-step guide to refactoring an include-oriented page-based spaghetti mess of an application into one that is autoloaded, dependency-injected, unit-tested, layer-separated, and front-controlled.
  • Solving the N+1 Problem in PHP is guide to identifying and resolving a particularly nasty performance problem related to building domain objects using SQL queries.
  • Aura for PHP is a collection of truly-independent library packages; not only are they decoupled from any framework, they are also decoupled from each other so that none of them have any dependencies.
  • Blogs at paul-m-jones.com

Hugo Hamon


Franziska Hinkelmann


Developer Shout-Out

The Developer Shout-Out recognizes developers in the community for their contributions.

For this episode the panel guests, Paul, Hugo, and Franziska nominated Matthew Weier O’Phinney for the Developer Shout-Out segment.

Thank you, Matthew Weier O’Phinney for your great work on PSR-0 & PSR-7. A $50 Amazon gift card is on its way to you.

$50 Amazon gift card sponsored by Laracasts

Laracasts

It's like Netflix for developers.

Show Notes Credit

Chris Shaw

Thank you Chris Shaw for authoring the show notes for this episode!

If you'd like to contribute show notes and totally get credit for it, check out the show-notes repo!