Accident.com
July 2023

Migrating Legacy Web Application to Laravel

The best way to adapt modern framework without freezing feature development.

Services

Backend, Security, Database

Platforms

Web and Mobile

Migrating Legacy Web Application to Laravel

Product Overview

The current product was developed using CodeIgniter 3.1.5 PHP framework and since the inception there were no updates done in particular to CodeIgniter(CI) framework version. It lacked support and was not the best solution for an ever growing business.

There was no pause on the features build for the product. We initially thought about migrating to a JS based framework as a complete rewrite, but the proposal didn't make sense in terms of Time / Money and also meant pausing feature development on existing project. It also meant switching technologies : PHP to JS, which would mean upskilling or hiring for skills.

With technology advances, it was noted that it was better migrate to a newer PHP framework rather than upgrading existing CI framework. Our goal was to migrate to Laravel with minimum development effort as writing everything from scratch in Laravel was a huge effort and it would have impacted business.

The Approach

There are two approaches when it comes to migrating existing application to any other platform i.e. we either decide on a date/flag-day that we will launch the product with migration or have an in-place/side by side migration.

We might feel flag-day would be appropriate to get things done but it is the more drastic path. This would mean freezing all the existing/future development and rewriting the application completely. In any project, commercial or open source, this is a topic for debate. For a commercial project, it puts a cost on the migration: (number of developers * billing * n months) + opportunity cost of the development pause where n will realistically be six months minimum based on project development effort. This estimate is hard to get approved by the project stake holders. In addition it is rare that development work gets completed on time due to uncertainties. That six months can creep to a year and even beyond rapidly.

With the in-place/side by side migration, we add Laravel to our application so that it has the first opportunity to service a request (route). Otherwise, it hands off to the CI framework.

This approach has two immediate advantages:

  • We can develop all new features immediately on Laravel as well as use Laravel features and facades within the CI framework.
  • It also means we can migrate CI controllers on a case-by-case basis as time and resources allow.

With this there is no promised flag-day deadline to miss, and there's no frustrating feature pause.

Taking the Call

Part of convincing the developers and stake holders is being able to reference that Laravel is now the number one web application framework on GitHub across all languages.

Other important arguments include:

  1. Retain employees: Let’s face it, developers to engage in projects that use current frameworks and which support modern versions of PHP (i.e., greater than or equal to 7.1).
  2. Have to eventually: This is a corollary of the above point. If one doesn't migrate to a modern framework, then they inevitably face each of the following consequences.
  3. Lose employees/developers, code grows more outdated and consequently prove more difficult and costly to upgrade eventually.
  4. Running on frameworks that have passed end-of-life and end-of-support which means security holes will be discovered but remain unpatched and we will be forced to run older operating systems to run older versions of PHP for framework compatibility yielding yet more known but unpatched security loop holes.
  5. Develop with modern techniques and services: Laravel makes it incredibly easy to use modern features such as events with listeners, job queues, an integrated command line interface, broadcasting, caching, scheduling, modern templating engine(blade), database abstraction, and ORM, and more.

The Migration

Step One: Install Laravel

The first step is to install the Laravel application base files alongside the existing application files. Start by installing Laravel using its documentation into a separate directory and then move the files over to the legacy application root directory in a piecemeal fashion.

We need to resolve any filename or directory conflicts, and we should do this by moving the files out of the way and renaming or refactoring them rather than altering Laravel’s files. The level of effort here is framework dependent, but the good news is that it was very easy for CodeIgniter. Lastly, if we are running a custom or non-application framework, we can still use the technique we are demonstrating here. Continue reading and pay particular attention to moving but keeping the index.php in step two below.

List 1:
Initial Setup for Laravel + Legacy app

After we complete the file moves as shown by example in List 1, examine any files remaining in the Laravel directory and move them if necessary/desired. Also, note the example was based on Laravel v5.x so the effort may vary for other versions. As well as the base Laravel files, we also need the actual Laravel framework and supporting packages. Integrate the lines shown in List 2 to the composer.json file (ensuring we match this to our version of Laravel).

List 2:

Composer dependencies

We should now run composer update to install Laravel and it’s dependencies. We should also examine the other sections of Laravel’s composer.json file including the config, extra, and scripts sections and copy them across.

Before you proceed any further, you should check that your legacy application continues to work as expected. While we have installed Laravel’s files and supporting libraries, we have not changed index.php so your application should run as it always has. If you have integration tests, they can really shine here. If you don’t, consider writing them as you port functionality over to Laravel. Diagnose and fix any issues now.

Step Two: Activate Laravel as the Default Framework

We need to verify that we completed Step One successfully. To do this, move the index.php out of the way (e.g., mv index.php legacy_index.php) and copy over Laravel's own index.php to replace it. We need to make sure Laravel starts up instead of the legacy application. If it works, we will see the standard Laravel application welcome page. If this does not work, diagnose and fix those issues now.

When finished, leave Laravel’s index.php in place. The handoff to the legacy framework happens within the Laravel application and not index.php.

Step Three: Hand Off to Legacy Framework

There are two ways to hand off to the legacy framework:

  • 404 error handler
  • catch-all route
Using a 404 Handler

In Laravel, if a route does not exist to handle a request, it throws a 404 exception. In Laravel v5.x, this gets handled in app/Exceptions/Handler.php:

Exception Handler

We augment the register() function to handle 404 exceptions differently by handing them off to the CI framework— here's a sample code snippet example.

Handling the 404 Exceptions

Before we fill in the detail of pass to CodeIgniter framework contents of index.php above, we need to decide how to actually handoff a request. We copy in the contents of legacy_index.php and it would work fine. However, as we migrate more and more elements to Laravel, we’ll find various complications that make this unwieldy. A better way to handle the CI framework within Laravel is to treat it as a Service Provider. For example, we could create a file app/Providers/CIServiceProvider.php as shown in List 3.

List 3:
CodeIgniter ServiceProvider

Register the new Service Provider in config/app.php:

ServiceProvider Config

Now that we have our CI framework Service Provider, we can return to the 404 exception handler's (app/Exceptions/Handler.php) handleException() function and add the missing piece:

CI Service Provider in Exception Handler

There are some significant advantages to using a Service Provider and putting Laravel first:

  • We can use all of Laravel’s facades immediately in CI code (e.g., Cache::, Queue::, Mail::, and more.)
  • We can migrate code on an action by action basis rather than controller by controller or even have Laravel handlenew action based requests for existing CI controllers.
  • We can eventually cleanly and simply remove the CI framework by removing the 404 handler lines, the entry in config/app.php, CI related packages from composer.json, and the legacy service provider.
Using a Default Route

This is the second way to handled the side-by-side migration. At the end of Laravel’s routes/web.php file, we add:

Handling all CI Routes

This route catches all routes not having a specific previous match in Laravel in the same way the 404 handler does. This then hand off to the CI framework in a controller (app/Http/Controllers/CIController.php) as follows:

CodeIgniter Controller

This also works, but be aware we have entered Laravel's HTTP kernel handling, and loaded and run all middleware associated with the web routes. This solution can be useful in some circumstances, but the 404 handler method is generally more efficient.

Continuing the Migration

You can proceed with the migration on a controller by controller basis (or action by action) along with the views andmodels as necessary.

References:

https://www.barryodonovan.com/wp-content/uploads/2019/04/migrating-legacy-web-2019-mar-phparch.pdf

Testimonials

Don’t take our word for it.
See what our past clients say.

“Best Development Agency”

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non dolor urna, ullamcorper feugiat elementum non et erile tortor. Dignissim eu faucibus et, congue. Tempus commodo vitae consequat eget et quis non tincidunt idert.

John Carter - Code Webflow Template
John Carter
Head of Product at Twitter
Company Logo - Code Webflow Template

“One of the best agencies out there”

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non dolor urna, ullamcorper feugiat elementum non et erile tortor. Dignissim eu faucibus et, congue. Tempus commodo vitae consequat eget et quis non tincidunt idert.

Will Spark - Code Webflow Template
Will Spark
Engineering VP at Google
Company Logo - Code Webflow Template

“True Experts in Web Development”

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non dolor urna, ullamcorper feugiat elementum non et erile tortor. Dignissim eu faucibus et, congue. Tempus commodo vitae consequat eget et quis non tincidunt idert.

Sam Parker - Code Webflow Template
Sam Parker
VP of Marketing at Twitter
Company Logo - Code Webflow Template

“Best Development Agency”

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non dolor urna, ullamcorper feugiat elementum non et erile tortor. Dignissim eu faucibus et, congue. Tempus commodo vitae consequat eget et quis non tincidunt idert.

John Carter - Code Webflow Template
John Carter
CEO at Facebook
Company Logo - Code Webflow Template

“One of the best agencies out there”

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non dolor urna, ullamcorper feugiat elementum non et erile tortor. Dignissim eu faucibus et, congue. Tempus commodo vitae consequat eget et quis non tincidunt idert.

Will Spark - Code Webflow Template
Will Spark
Engineering VP at Google
Company Logo - Code Webflow Template

“True Experts in Web Development”

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Non dolor urna, ullamcorper feugiat elementum non et erile tortor. Dignissim eu faucibus et, congue. Tempus commodo vitae consequat eget et quis non tincidunt idert.

Sam Parker - Code Webflow Template
Sam Parker
VP of Marketing at Twitter
Company Logo - Code Webflow Template
   Previous
Next   
Let’s get in touch

Ready to start working together with us?

 Email Icon - Code Webflow Template

Send us a message!

Don't miss out on the opportunity to take your business to new heights. Contact us now and let's embark on a journey of success together.

Contact us
Development Execution - Code Webflow Template

Browser our packages

From startups seeking a strong foundation to established enterprises aiming to optimize operations, our scalable and flexible packages cater to businesses of all sizes.

Browse packages