Migrating a legacy PHP application to Laravel

When I started working at Zonneplan in 2016, I was tasked with the goal
to migrate our legacy PHP architecture to a standardized solution.

The application itself was running just fine, but to allow the team to scale, we needed to make sure
that the architecture could scale with it. Since I had previous experience with Laravel,
we choose to adopt it as our framework-of-choice.

At the time, the main application that had to be migrated contained about 100.000 lines of code, mostly
written in a non-MVC manner combining both HTML and PHP in loose files.

Rewriting this application into another framework would have taken months (at least) and would probably have resulted
in a feature-freeze and dozens of bugs in the process.

In the end, we did not rewrite the application, but simply "wrapped" it in a Laravel container. In this article,
I will show you we did it.

Heads up: this is not going to be pretty, but it works oh-so-well 🙈

First steps: get your directory structure in order

Create an empty Laravel application
Choose whatever method you wish to create a new Laravel application, as long as you end up with an empty skeleton.

Create a new folder to contain your legacy application
We called it legacy-app to make the distinction between the regular app folder clear while still showing it's purpose.

Create a layout file wrapper

Create a fallback controller

Last, we created a fallback controller that acts like a proxy between Laravel and our legacy application.

classLegacyControllerextendsController{publicfunctionindex(Request $request){$path=base_path('/legacy-app/').$request->path();// If the path does not end with PHP, assume we're requesting an index fileif(substr($path,-3)!='php'){$path.='/index.php';}return$this->renderPath($path);}protectedfunctionrenderPath($path){view()->addNamespace('legacy',base_path('legacy-app/'));if(file_exists($path)){returnview('legacy.index',['includePath'=>$path]);}else{abort(404);}}}

Conclusion

Migrating a legacy app into Laravel does not always have to be as hard as it looks.

This method of wrapping your application into a Laravel container allows you to keep developing new features
using new techniques while maintaining backwards compatibility.

This sure ain't "pretty code", but it gets the job done very well.

This code is still powering our codebase as to this day and basically has not changed since I have written it.

If you're tasked with the job of migrating a legacy application into Laravel,
I hope this technique will make things easier for you.