The best way to adapt modern framework without freezing feature development.
Backend, Security, Database
Web and Mobile
Building framework bridges
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.
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:
With this there is no promised flag-day deadline to miss, and there's no frustrating feature pause.
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:
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.
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).
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.
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.
There are two ways to hand off to the legacy framework:
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:
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.
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.
Register the new Service Provider in config/app.php:
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:
There are some significant advantages to using a Service Provider and putting Laravel first:
This is the second way to handled the side-by-side migration. At the end of Laravel’s routes/web.php file, we add:
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:
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.
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
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 usFrom 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