Over the past months I’ve talked to several companies that run a symfony 1 codebase, sometimes as old as symfony 1.0, which is big, very big. Often these applications or websites are at the heart of their business. Yet, Symfony2 is stable now, and symfony 1 support is going to stop at some point. Regularly, they ask me for advice on migrating their legacy codebase to a brand new Symfony2 project. Often enough, I have to inform them that migration from a symfony 1 to a Symfony2 codebase is a lot of effort and a huge investment in time (and therefore money). Many companies then wonder whether they should do it at all. The thing is, there is no need to do it all at once.
It is much easier to do a gradual migration. Start with one part of your application, and bit by bit migrate your logic and application. The traditional way of doing such migrations is to create a new project and have parallel development on the old and the new version of the application. The problem with this, though, is that when you make a change to your old application, you have to make the same change in the new codebase, essentially doubling the amount of work for each feature you need to implement.
Wouldn’t it be much cooler if you only need to change this once? This is of course an option. You could wrap your old application into your Symfony2 application, and have different parts of your application be handled by different versions of your codebase. Once you’ve ported a new section of your application to Symfony2, you change the routing in your application to point those URLs to your Symfony2 bundle instead of your old symfony 1 project, and that part is done. You can move on to the next part.
A word of caution
While this approach is ideal because you can migrate in several phases, there are some issues with this approach. First of all, this will have a performance impact on your application. Instead of a single framework, you now use two frameworks for all your legacy pages. Result: An extra overhead because, well, two frameworks add more overhead than one. And though Symfony2 is in this case only a proxy, it does add an extra layer. Of course, you can use the cool caching features of Symfony2 to add a caching layer in front of your symfony 1 application (which might actually speed up your application), but this definitely does not apply to all projects. So before simply applying some caching to your application, think about whether it will work. And keep testing 🙂
Another issue is sessions. If your application works with authentication and authorization, you’ll now have to work with two different systems that have a different approach to authentication and authorization. So far, I have not yet figured out how to manage this, but in the projects I’ve used this approach for so far, I didn’t really need to do this. But this is something you really need to consider.
I created a simple bundle that could assist in using this approach. The IngewikkeldWrapperBundle adds a simple fallback route in your Symfony2 application, so that any URL not handled by your Symfony2 application is automatically forwarded to your legacy codebase. The legacy codebase handles the request and returns the response, and that’s it. And once you’ve had the time to work on porting a new part of the codebase to Symfony2, you simply add a route to your new bundle that matches the old URL pattern for that part of your application, and Symfony2 starts serving that part instead of symfony 1.