Two Kinds of Legacy Code Upgrade

I often speak with project owners or CTOs, who ask for help with legacy project upgrades. They typically want something like "upgrade to PHP 8.0" or "upgrade to Symfony 5.4". There are two ways to do that.

Which one is the best for you? Let's ask the important question first.

"Do you plan to sell the project next year
or will you work on it for the next 5 years?"

Put in other words:


Let's say the goal is to upgrade from PHP 7.0 to PHP 7.4.

1. The Superficial Upgrade

This kind of upgrade is like a house renovation, not for your own living but for selling it to someone else. You want to increase the perceived value of the house, but you need to care about the quality of the renovation.

The same applies to code. You want to increase the perceived value of the codebase, but you need to care about the quality of the code.


When we say in the news that our code base uses PHP 7.4, what does it usually mean? 2 things:

  1. The composer.json uses this version as a minimum:
{
    "require": {
        "php": ">=7.4"
    }
}

  1. The Dockerfile uses the exact PHP version:
FROM php:7.4-cli-alpine

This may seem like it allows you to say in a job advertisement that your project "use PHP 7.4".


But what does the code really look like?

class ProjectManager
{
    private $managerName;

    public function __construct($managerName)
    {
        $this->managerName = $managerName;
    }

    public function handle($project)
    {
        if (date('l') == 'Wednesday') {
            $this->organizeMeeting($project);
        }
    }
}

You're right; we define the PHP version number in the composer.json and Dockerfile.


But we don't really use any of PHP 7.4 features:


Still, you can tell your boss, who doesn't understand the complexity of the upgrade, that you use PHP 7.4 already. Collect the bonus for handling the upgrade and make them happy. At least for a year or two, till the technical debt hits you back.


2. The Long-Term Value Upgrade

The other way is like reconstructing a house for you and your family to live in for at least the next 20 years.

You care about the usability of the house:

It's not about making it look nice and shiny but about making it work for you in the long- term.

It takes more time, and it's more expensive because you deserve to have a decent home. It might be frustrating at the start, as you must take down old paint and furniture and check the sewage and electricity wires. After 2 months of reconstruction, the house looks much worse than you started.

But in the long term, you know for sure the foundations are done correctly, and you don't have to worry about any "surprises" like turning on the washing machine and induction cooker table.


The same applied to the legacy codebase upgrade: you use the latest PHP features right away:

-class ProjectManager
+final class ProjectManager
 {
     private $managerName;

-    public function __construct($managerName)
+    public function __construct(string $managerName)
     {
         $this->managerName = $managerName;
     }

-    public function handle($project)
+    public function handle(string $project): void
     {
-        if (date('l') == 'Wednesday') {
+        if (date('l') === 'Wednesday') {
             $this->organizeMeeting($project);
         }
     }
 }

This code is in much better shape than the one above, and it uses only PHP 7.1

It allows hiring new people faster, adding new features with fewer regression bugs, and it's easier to maintain.


In Rector team, we always go for the long-term value, as we care about clients' success and exponential growth, not about short-term profit that will put the company down.


Which one do you prefer?




Do you learn from my contents or use open-souce packages like Rector every day?
Consider supporting it on GitHub Sponsors. I'd really appreciate it!