LEGACY · MIGRATION

Modernising legacy PHP

The overgrown monolith is rarely pretty — but it earns money. Here is how to modernise legacy PHP without risking operations.

Almost every company with a few years behind it has one: a PHP system that has grown over time, runs business-critical processes — and that nobody likes to touch anymore. Old PHP version, no tests, tangled responsibilities, knowledge living in a few people's heads. The reflex to "just rebuild it from scratch" is understandable. In practice, it is usually the most expensive and riskiest option.

I have modernised exactly these kinds of systems — including as lead developer at ALDI Nord, where an overgrown monolith was migrated to Symfony 6.4. This article summarises how to approach it without endangering operations.

Why "just rebuild it" so often fails

The big rebuild (big-bang rewrite) sounds tempting but has three structural problems:

  1. The legacy system keeps evolving. While you rebuild for months, the running business still needs changes. You are aiming at a moving target.
  2. Hidden knowledge is lost. Grown code holds years of business logic — special cases nobody documented. A rewrite loses exactly these invisible rules.
  3. No value before the big bang. You invest for a long time without shipping anything, and the switch-over becomes a single risky moment.

The better path: strangler-fig

The proven alternative is the strangler-fig pattern (named after the fig that slowly grows around a tree). Instead of replacing everything at once, the new system grows around the old one — taking over functions piece by piece until the legacy system eventually becomes obsolete.

Concretely, this means:

  • A modern framework (such as Symfony) runs alongside the legacy system.
  • A routing layer decides per request whether the old or new system responds.
  • New features and refactored areas are built in the new system; the rest stays untouched for now.
  • With each migrated part, the legacy footprint shrinks — until it disappears.

This way you deliver value continuously, keep the system running at all times, and limit risk to small, manageable steps.

Step 1: create visibility

Before changing legacy code, you need a safety net. Without tests, every change is a blind flight.

  • Characterisation tests capture the current behaviour — even the buggy parts. They document what the system actually does before you touch it.
  • Static analysis (e.g. PHPStan) surfaces obvious risks and dead paths.
  • Monitoring shows which parts are used at all — often you can simply remove dead code.

Step 2: the right order

Not everything is equally urgent. I prioritise along two axes: business value and change frequency. Areas that are touched often and matter are modernised first — that is where clean structure pays off fastest. Stable, rarely changed parts can stay untouched for a long time.

Step 3: PHP version and dependencies

An outdated PHP version is a security and cost risk. The jump from PHP 5.x or early 7.x to PHP 8 brings noticeably better performance, type safety and maintainability. This works best incrementally: update dependencies, modernise automatically with tools like Rector, and secure each step with tests.

Step 4: get knowledge out of people's heads

The biggest risk in legacy systems is not the code but the bus-factor problem: if only one person knows how something works, every change is fragile. Modernisation therefore also means externalising knowledge — into tests, documentation and clear structures that speak for themselves.

What this means for you

Legacy modernisation is not a prestige project but risk management. Done right, it lowers maintenance costs, closes security gaps and makes your system changeable again — without your day-to-day business ever standing still.

The key is the incremental approach: make things visible, secure them, replace them in small steps. No big bang, no blind flight.

Do you have a system nobody likes to touch? I am happy to take a look and tell you honestly whether and how modernisation is worthwhile. Let's talk. You can read more about my work under Symfony & PHP development.

Let’s build it.

Tell me about your project — you’ll always talk to the person who builds it.

Start a project