How to migrate from one PHP framework to another – gradually

Picture the scene: Your development team is getting more and more frustrated with the framework that a project was built on. Or you’ve taken on a new project, and the code is a mess. You don’t want to be stuck with that codebase forever.

In a large project, you may not have the option or the time (or indeed the desire) to do a big bang migration from one framework to another. The company may not let you do it. Aside from being boring work, it’s also pretty risky – and it could absorb a large chunk of time. Or it’ll never be completed.

The first thing you should do is trial the new framework, either as a dummy project or with a safe copy of your current project. Basically, make sure this is a move you want to make. You don’t want to start another migration before the first one’s done…

Once you’re sure you want to proceed, here’s what to do. (Hopefully it goes without saying this shouldn’t be done directly in production…)

1. Rename the index file to index-old-fw, or whatever the name of the old framework is. For instance, if you wanted to move away from CakePHP (I’m choosing a framework at random here), you might rename index.php to index-cake.php.

This will break everything.

2. Take the index file for the new framework, and name it according to your new framework. Let’s say you’re using Laravel – you might rename index.php to index-laravel.php.

3. Now create a new index.php and write some simple logic that will map to one framework or the other. Something like this:

<?php
$laravelPaths = array('/test-laravel');
if (in_array($_SERVER['REQUEST_URI'], $laravelPaths)) {
  require 'index-laravel.php';
} else {
  require 'index-cake.php';
}

(This is a really simple example; you’ll need to modify it for partial matches to handle things like query parameters later. For now the point is to get one page working on the new framework.)

4. Put the new framework code in a logical folder so it can be loaded in the new index file. This largely depends on how your current framework is set up. You probably won’t want to mix two frameworks in the same folder, as folders may have overlapping names – possibly even files. You’ll have to handle all the paths for the new framework in your new index file. The goal is to keep all your existing pages working fine on the old framework.

5. Set up the new test page in the new framework.

By now you should start to see how it’s possible to mix frameworks in a project. This isn’t a permanent solution; it allows you to start using a new framework and gradually migrate across to it.

The early part of a migration will be tricky. Unless you can reuse API code across both frameworks, you’ll probably need to rebuild a lot of code in the new framework. This is a perfect opportunity to write unit tests if you’re not already using them. Focus on building one page (a good one is a static page, such as your About page or another page that doesn’t do much) – to do this you’ll need to build a lot of the core “scaffolding” code such as getting your site theme to display properly, connecting to the database (less important for static pages but needed later), and then things like logins and so on.

As you progress onto other pages, it will get easier as a lot of the base work can be reused. You’ll need to update the URL list in your index file to map specific URLs to the new framework as pages get moved. You can write code to handle wildcard URLs so you can move entire sections of your site to the new framework, e.g. product landing page. It’s a lot of work but it can also help to rationalise your entire site, especially if there’s a lot of odd standalone pages that nobody really remembers creating!

Once the base code for the new framework is in place, you’ll have a big advantage and a big disadvantage with future work:

  1. Advantage: New functionality can be built entirely on the new framework.
  2. Disadvantage: Repetition/duplication across the two frameworks – especially with theme files.

You can improve the situation by building bridging code that will help you to migrate. Code that is framework-agnostic and can be used by both frameworks.

Keep track of how many URLs you have across the site and how the migration is going. At some stage you’ll reach a “midpoint”, which is when you need to replace your URL array. Instead of sending only specific URLs to the new framework, send everything except the URLs you specify in that direction. This requires good knowledge of your application architecture, but it can be done. Remember you can use wildcards to target entire sections that need to stay on your old framework for the time being.

I won’t claim this to be a particularly clever or elegant way to do things, but it works. So far, I’ve used it for the following migrations:

  • deprecated in-house legacy framework => Zend Framework 1
  • Drupal 7 => Laravel 4.2
  • custom framework => CodeIgniter
  • custom framework => rebuilt custom framework

Hope it’s of use to someone.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s