Skip to Content
Course content

232: Strangler Fig Pattern for PHP Modernization

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you have an ancient, massive banyan tree in your backyard. It’s beautiful in a chaotic way, but the roots are cracking your foundation and the branches are blocking all the light. You want a modern, structured garden, but you can't just rip the tree out in one afternoon—it's too big, it's holding up the fence, and if you kill it too quickly, the whole yard might collapse.

Instead, you plant a "Strangler Fig." This new plant starts small, grows around the old tree, and slowly sends its own roots down to the ground. Over time, the new plant takes over the functions of the old tree. Eventually, the old tree dies and rots away, leaving you with a strong, healthy new tree in the exact same spot, without you ever having to deal with a catastrophic collapse.

In the world of PHP, this is exactly how we handle "legacy modernization." We don't do the "Big Bang Rewrite"—where you spend six months building a "Version 2.0" in a vacuum, only to realize you forgot 40% of the edge cases in the old system. Instead, we use the Strangler Fig pattern to replace the old app piece by piece while it's still running in production.

The Danger of the Big Bang Rewrite

I've seen too many developers fall in love with the idea of a total rewrite. They look at a PHP 5.6 codebase filled with 2,000-line files and global variables and think, "I can just rewrite this in Laravel in three months."

They're always wrong. Why? Because that "ugly" legacy code contains years of bug fixes and business logic that isn't documented anywhere. If you rewrite everything at once, you're not just upgrading the language; you're guessing at the business rules. The Strangler Fig pattern removes that risk. You migrate one route, one feature, or one API endpoint at a time.

Putting the Proxy in the Middle

To make this work, you need a "facade" or a routing layer that sits in front of both your legacy app and your new modern app. This is usually handled at the web server level (like Nginx) or via a small PHP entry point. The proxy decides: "Does the new app handle this request? If yes, go there. If no, send it to the legacy monster."

// A simplified conceptual proxy in your index.php
$requestUri = $_SERVER['REQUEST_URI'];

// List of routes we have successfully migrated to the new system
$migratedRoutes = [
    '/api/v2/users',
    '/profile',
    '/login'
];

if (in_array($requestUri, $migratedRoutes)) {
    // Send the request to the new modern framework
    require __DIR__ . '/modern_app/public/index.php';
} else {
    // Fall back to the legacy spaghetti code
    require __DIR__ . '/legacy_app/index.php';
}

Carving Out the User Profile Page

Let's say you have a legacy page called `user_profile.php` that's a nightmare of mixed HTML and SQL queries. Instead of rewriting the whole site, you target just that one page.

  • First: You build the User Profile feature in your new framework (e.g., Symfony or Laravel), ensuring it connects to the same database.
  • Second: You update your proxy/Nginx config to route /profile to the new app.
  • Third: You test it. If it breaks, you just flip the proxy switch back to the legacy app. No downtime, no panic.
  • Fourth: Once you're confident, you delete user_profile.php from the legacy folder.

You've just "strangled" one piece of the legacy system. You repeat this process for the checkout page, the search function, and the admin dashboard. Eventually, the legacy folder is empty, and you can delete the entire old directory structure.

Knowing When to Cut the Cord

The hardest part isn't the code; it's the discipline. It's tempting to keep adding "just one more" feature to the legacy app because it's faster than setting up the proxy for a small change. Resist that urge. Every single line of code added to the legacy system is a debt you'll have to pay back later.

The goal is to reach a tipping point where the legacy system is so small that the remaining pieces can be moved over in a single weekend. That's when you finally delete the proxy and let the new app take over the root directory entirely.




📋 Practical Task

Implementing a Route Proxy for Legacy Migration

You have been handed a legacy PHP project. The legacy app lives in a folder called /legacy, and you are building a new version in /modern. Your task is to create a routing_proxy.php file that acts as the entry point for the application.

Requirements:

  • Create a script that checks the $_SERVER['REQUEST_URI'].
  • If the URI starts with /api/v2 or is exactly /dashboard, the script should include the file modern/index.php.
  • For all other requests, the script should include legacy/index.php.
  • Add a simple echo statement at the very top (which you can remove later) that tells you which "version" of the app is currently handling the request, so you can verify your logic is working during testing.

Files to simulate for your test:

// legacy/index.php
echo "This is the legacy system.";

// modern/index.php
echo "This is the modern system.";
Rating
0 0

There are no comments for now.

to be the first to leave a comment.