PHP Applications Modernization: Challenges and Approaches in 2023
The fact that PHP projects can run for many years is one of the most awesome strengths of this technology. But at the same time, outdated versions of PHP with unsupported frameworks and libraries cause a lot of problems for product owners. Your system may still work but have some issues preventing it from adding new features and scaling. Still, the main challenge of modernization is to update without harming the current product, which may lead to losing customers and money.
If you are among those who experience difficulties in finding PHP developers able to scale hours immediately to modernize your app, or your previous developers have not lived up to their commitments and left you with nothing right before the deadline, this article is for you. As a PHP/DevOps Group Leader at MobiDev, I have worked on dozens of PHP projects and would like to share our approach to modernizing legacy applications to help you tackle this task in the most efficient way.
6 Signs Your PHP Application Needs Modernization
First of all, let’s start with a quick diagnostic process to find out if your PHP app really needs to be modernized. There are certain signs which can tell you that something is wrong.
From a business point of view
- Unpredictable behavior of the application causes poor UX
- The price of infrastructure support is too high
- Security breaches cause a bad reputation
- You lose your clients because your application is too slow
From a tech point of view
- Unstable work of the application: errors, outages, long downtime
- Security issues caused by an outdated tech stack and/or vulnerable code
- The current tech stack no longer meets your business needs. There are better technical alternatives.
- Hard to add new features because of messy source code and complex business logic
- There are unsupported or unmaintained libraries/technologies
If you come across the above-mentioned issues, your app really needs to be updated to stay competitive in the market. The more points that are true for you, the sooner you should start reviving your PHP project.
Why You Should Use Supported PHP Versions
At the time of writing this article, the officially supported versions of PHP are 8.0, 8.1, and 8.2. But according to statistics, about 80% of PHP users are still on PHP 7.4 and lower. PHP 8 has been out since November 2020, but only 7.9% of websites have made the switch to it:
There are many reasons to stay on the supported version of PHP and keep your product updated. The most preferable option is to stay on the latest stable version since it provides you with better UX and improved application performance. Among other reasons, you should consider the following:
- Security. Most of the security issues in PHP apps are related to outdated versions of PHP. Security vulnerabilities can cause data loss, data leaks, outages, etc.
- Support of modern libraries. Outdated versions of PHP may cause issues with updates to newer versions of libraries/frameworks. Libraries and frameworks can also be vulnerable and sometimes you may be unable to update separate libraries without PHP update.
- Integrations. To speed up development, you often need to use third-party services that can provide libraries, clients, and SDKs integrations. You may not be able to use such services until you update to newer versions of PHP. Same story with PHP frameworks. There is a higher chance to find integrations for modern frameworks than for outdated ones.
- Adding new features. Newer versions of PHP provide a variety of capabilities to speed up the development of new features and improve the readability of the code. That means you can easily expand your team with new developers. Also, many engineers prefer to work with modern tech stack rather than with legacy applications. This is also a reason to think about regular updates and stay on a stable modern version.
- Performance. Core PHP developers are constantly working on improving PHP performance. For example, JIT-compilation has been added since PHP 8, which opened the door for enhanced data processing.
Challenges of Migrating Legacy PHP Applications (To Migrate or Not to Migrate?)
Modernization of outdated code is crucial, but it comes with some risks. Migrating a legacy PHP application presents challenges for both a development team and the product owner. Let’s imagine how developers and product owners see the same situation:
And they are both right. They have to find some kind of compromise so that the project effort is justified. In most cases, it is possible to support current applications and do updates step by step while also adding new features. The development speed would not be so great in this case though.
The main point is that developers need to do extra steps before starting the migration process or adding new features such as:
- understand legacy logic laid by previous developers
- do refactoring in case of dirty code
- prepare code for adding new features.
Only after this work is done will PHP developers be able to add new functionality. Product owners will benefit from such work in the long run. After some time, the speed of the app will increase, and the stability and security will also grow. This is a kind of investment in the future of your application.
Read also:PHP 8 Migration Guide for Product Owners
Two Approaches to PHP App Modernization
When it comes to PHP app modernization there is one difficult question: should you continue using the existing application after updates or should you rewrite everything from scratch on a modern tech stack? Answering this question gives us two main approaches to PHP app updates.
Approach 1. Rewrite everything from scratch
Rewriting your app from scratch is the most guaranteed way to achieve quality and stability of the application. But a lot depends on the state of the current software product. Sometimes it is really better to rewrite everything from scratch because it will take less time than fixing and updating legacy code.
In this case, a development team can start working on a new application with modern technologies using the old app as a reference to business logic. The newest versions of PHP or some alternatives like Node.js or Ruby can be used here. This will provide a better understanding of the business needs, taking into account previous user experience, parts of the application that work well for users and parts that can be improved. As a result of this work, you will get a beautiful modern application based on your legacy one.
Let me answer the questions that you may have at this stage:
- Is it an expensive approach? Yes. Such work will consume a lot of time and money.
- Should I do a feature freeze? Probably, yes. You would pay twice if you create new features on a legacy application and after that you need to create the same features on a modern application again.
Approach 2. Stay with a current application
The previous approach will not work for most businesses. In most cases, a business needs new features to live. Using the current application is possible in cases when the approximate time for an upgrade will take less time than rewriting everything from scratch. A lot depends on the current technology stack and the technical state of the system.
What parts are most critical to update? Are there any security vulnerabilities? Are there any libraries that are not supported anymore?
Only after analysis, can technical experts suggest an upgrade plan. The most valuable activities will be done first. During the upgrade process, PHP developers can add new features to the current application as well.
What issues can bring such an approach?
- Potential non-obvious bugs. Fixing one bug may bring on another bug because of the level of complexity and quality of the legacy code.
- Difficulties with compatibility. You can update the version of PHP and some parts will work well but some parts will not work because of breaking changes.
- Complex logic. If you have a complex application with a huge code base, then upgrades should be done step by step. That means there would be part of logic with updates and part of logic without updates. These may bring some temporary dirty hacks, extra levels of complexity, and cause some difficulties in the onboarding of new developers who are not familiar with the project.
Book a consultation with a MobiDev expert to find out which approach is best for your project!
Want to get in touch?contact us
Workflow for PHP App Modernization at MobiDev
Regardless of which of the above-mentioned approaches you choose, the process of PHP app modernization will look almost the same. Based on our experience with many legacy applications, I can say that this workflow is the most efficient for both the product owner and the development team. It consists of 10 steps:
Step 1. The client sends a request for a project review to a technical expert.
Step 2. The technical expert analyzes the project and discusses with the client the possible ways of modernization and estimated timelines.
Step 3. The client requests a development team that will start working on a selected approach.
Step 4. Containerize the application. Docker will help with this. This allows for adding an extra isolation layer for the parts of the app. With Docker, we can easily manipulate any version of the service that we need for application functionality.
Step 5. Deploy everything in a sandbox environment for testing and development.
Step 6. Involve the QA engineer. Start testing the application to find the most critical issues.
Step 7. Prioritize the list of issues and start working on them.
Step 8. Work on updates and fixes iteration by iteration.
Step 9. (optional). After the stabilization of the application, new features can be added as a priority to updates.
Step 10. Your software is upgraded and ready to go.
Our Case Studies for PHP Legacy Software Modernization
Let’s go through some cases from our experience that will illustrate the solution of business challenges with the modernization of legacy PHP applications. These cases include comments from project developers that will help you better understand why a specific solution was chosen.
Case Study #1. Updating Legacy Laravel-Based Subscription Platform
The client came to us with a request for the modernization of the PHP platform in a critically short time frame. Since the previous developers of the project failed and didn’t do what they promised, the client needed a reliable team that would take up the challenge and meet the deadlines.
- Build the back end for the existing front end
- Find and fix issues preventing the system from working correctly
- Prepare the product for adding new features
The initial request was to rebuild the platform, but after code assessment and analysis of the client’s business needs, our PHP development team suggested improving the existing system instead of rewriting the product from scratch. Such a decision was influenced by the following factors:
- The platform was already in production and had an active user base. It was crucial for the business to keep the product running.
- Our client had a limited budget and timelines to make the system stable and prepare it for adding new features.
- Build the back end for the existing front end
When we delved into the project, we found out that its deployment, including the assembly of the front end, took place directly on the server, which required routine manual work, and significantly increased the time and cost required for debugging.
We’ve integrated Ansible, a software provisioning and configuration management system, and added rules to automatically build, deploy and update the software. This helped the client to save on servers since the assembly of the front end on the server required quite large capacities, which was unreasonable for everyday tasks.
- Find and fix issues preventing the system from working correctlyThe fact that the platform was written on an outdated version of the Lavarel framework led to unstable operation of the entire system (unpredictable errors, inability to use stable modern libraries, slow response from the server, etc.). Moreover, the PHP version also needed an update. Bugs in the framework plus PHP bugs were superimposed on project code bugs that created a danger to the security of customer data. So our PHP team decided to update Laravel to 5.5 LTS and PHP version to 7.0 on all servers as the latest versions at that time. This made it possible to eliminate system vulnerabilities and fix critical bugs.
- Prepare the product for adding new featuresThe poor quality of the code was a real challenge for the team, as a large part of the code needed refactoring. Plus, the project had no documentation, which complicated the process. Also, in order to use a third-party payment system, it was necessary to update the SDK since its version conflicted with the modules used by the project.
So code refactoring and regression work was done. After that, we were able to continue adding new features with modern technologies and an up-to-date version of our built-in and external modules. We created tech documentation that will allow the client to significantly save on onboarding new developers and adding new functionality in the future.
It was really challenging to update the framework version by version: 5.2 -> 5.3 -> 5.4 -> 5.5. because all of them were not backward compatible and each subsequent version radically changed either the architecture or the logic or even the names of the framework functions.
It was also important for the client to implement full GDPR compliance, at that time there was little information about it and it required additional research from the team. Overcoming these challenges assured the client that we have great expertise in PHP app development and they still trust us to introduce new features into the platform.
Case Study #2. Modernizing a Legacy App on Codeigniter Framework
Our communication with the customer started with the request to solve problems with the current API for CRM and mobile app with legacy code (Codeigniter 3, PHP 7.3). The client had tight deadlines: the software had to be updated within a month.
It is difficult to complete refactoring of the entire system in such a short period of time, so we decided to approach the improvement of the code very selectively and gradually. We drew up a plan with the most critical issues and started working on it.
- Update the highly outdated version of the framework to improve system performance
- Improve code quality under tight deadlines
- Configuring the mechanism of code delivery to the server
- Build new scaling infrastructure
- Update the highly outdated version of the framework
As the Codeigniter version of the framework was no longer supported, our PHP developers suggested gradually migrating the entire application to a newer version. The team created a plan with prioritization and division of all functionality into modules. Each module is a fully isolated functionality in a new project with up-to-date versions of dependencies and environments.
- Improve code quality under tight deadlines
The poor quality of the code caused additional problems. We had to spend more time studying the logic of each method, even for the smallest changes. At the same time, there was no way to fix everything at once due to the large size of the project and the large amount of functionality. Each change required a full understanding of the requirements for a specific feature, which could take a very long time and thus delay the release date.The solution was to refactor only those places whose functionality we were currently working on and proceed to other parts gradually. It made it possible to meet the deadline and save the client’s money. Within six months, about 80 percent of the code was already covered.
- Configuring the mechanism of code delivery to the server
At the start of the project, we had only one production environment available. Making edits to the code was very time-consuming and involved the risk of human error, which put the seamless operation of the application under attack.To mitigate these risks we needed to prepare a separate environment for testing and development. This was done with an automated code delivery process with Docker Stack + Ansible + Jenkins CI/CD, first for the test environment and then for the production environment.
- Building new scalable infrastructure
The old system was a monolithic server with a database and a folder to store all uploaded files. This architecture makes server load scaling very difficult and is obsolete in 2023, mostly suitable only for CMS out-of-the-box solutions but not for frameworks. Deploying new code to the server was only possible via FTP and had to be done manually.
To resolve these issues, first of all we moved the database and file storage from the server to remote services (AWS RDS, AWS S3). Third-party services are more stable and already have a backup mechanism that is more secure and helps to prevent data leakage.
The next step was to wrap architecture with Docker and isolate each service (NGINX, PHP and Socket) into containers. This made it possible to configure a stable automatic code delivery to the server (CI/CD) and also added opportunities for the optimization of the server resources.
Finally, we gradually moved the code to a newer framework (Codeigniter 4). For this purpose, a separate Docker container with a newer version of PHP was prepared.
Our team also created API Documentation (Postman Collection) with sample requests/responses from the server to help front-end and back-end developers easily communicate about the nuances of the API.
Initially, the project only had a month’s work to do. It was difficult to fit all the necessary improvements into such a limited period of time, and it was a really interesting challenge for us to choose what was the most critical.
It’s important to find ways to communicate the need for some code changes to the customer, even if the end user won’t see a clear benefit from it, but it’s crucial for functionality in the future. You need to have the trust of the customer and provide transparency in your decisions.
As a result of a month’s work, the client decided to continue cooperation with our team, and it made it possible to improve the code according to the plan prepared earlier without stopping the delivery of new functionality.
Case Study #3. Rewriting a Legacy PHP Communication Application From Scratch
The client’s request was to add an iOS app to the existing website, as well as improve the overall stability and maintainability of the system. In the process of the initial investigation, our team discovered that it was quite difficult to do this with the current architecture, which presented us with the following challenges:
- Bad app performance because of poor source code organization and quality
- Data split across several data storages made the support of the system complicated and time-consuming
- Multiple bugs and errors prevented the system from adding new features
Our PHP experts suggested rewriting the app from scratch since:
- Working with the existing code base and infrastructure would take more time than rewriting the application
- The client was not limited in time and was focused on maximum improvement
- The product was not used actively in the production environment
- Fixing bad app performance because of poor source code organization
During the analysis stage, our team discovered that the current application architecture was quite difficult to maintain and it did not allow for the easy addition of an iOS API. The project included pieces of code written in different languages and pieces of data stored on different platforms, such as MySQL, Neo4j and Google Cloud storage & Firebase. The logic was mostly client-side, with the notifications system being the only server-side asset.
So we set about creating a new version from scratch, moving the logic to the server side and consolidating the existing data into a single database. The existing legacy project helped us define the ultimate vision for the new app. We chose a new technology stack with a modern PHP framework and created an effective and scalable architecture.
The iOS app and its API were the main development focus and in the later stages, we recreated the existing website as a SPA using the same API. This approach was intended to provide easier iOS app integration, improve stability and performance, and provide opportunities for potential future improvements.
2. Consolidating data into a single database
The existing MySQL database was taken as the basis of development, as it contained the most data; however, we made improvements to its structure and indexes to provide better performance and data consistency. We also added a migration tool. Since then, the old version of the project has not been used for reference; instead, the functionality was rebuilt based on the customers’ current vision and ideas.
The development and testing servers were created on Amazon Cloud. We also added an admin panel to simplify user data management and an automatic documentation page for the API that updates in real-time and provides the ability to test API functionality for client-side developers.
3. Adding new features to the system
After the successful launch, we continued to improve the project. A cache was added and the database was moved to RDS to improve performance. Websocket notification was implemented to provide real-time chat. We’ve also updated the notification system to be easily configurable and include email and SMS notifications. The admin panel receives constant quality-of-life updates, including the ability to communicate directly with users through the associated account.
After about a year of cooperation, the new project branched off from the existing one, taking its data as a basis. This new project was later successfully migrated to another cloud service due to a number of legal and geographic reasons, and now it’s in constant development alongside the original one.
Currently, both projects are still actively used and allow users around the world to connect and share their experiences.
Why PHP is Still Good in 2023
If you have concerns about whether you should stay with PHP and opt for modernization or better migrate to another tech stack, let me dispel your doubts and tell you why PHP is still in demand in 2023.
Being an open-source PHP has a great development community that constantly improves this programming language. New frameworks and tools open the door for new opportunities and help PHP stay competitive in the market. Low cost for development and maintenance with very high performance and reliability made it the main choice for 77.5% of all the websites, according to W3Tech.
PHP is used by both enterprises and startups. It is a great option for long-term projects that want to grow since PHP is scalable by design. Also, it has a good loading speed, even on slow Internet connections. Since PHP 5.6, its performance has increased almost two times over.
In our experience, PHP is a great tool for the following types of projects:
- Server-side rendering (SSR) websites
- RESTful web services (API)
- Social applications that require scalable architecture and specific features like likes, dislikes, messaging, comments
- Server-less applications
- Complex systems with great functionality like ERP and CRM platforms
- E-commerce, marketplace, booking platforms
- Mobile Device Management (MDM) systems
- Healthcare projects that focus on security
Of course, PHP is not a silver bullet and it has certain drawbacks. For example, it’s not the best choice for CPU-consuming tasks. If you need to run heavy tasks with the best possible performance then it’s better to use other compiled languages like Golang, C++, or C.
If all of the above meets your business needs and you are ready to modernize your PHP application, let’s get started without wasting time. I know that the question of modernization is usually raised when everything is already on fire and it is quite difficult to find a reliable partner capable of quickly allocating resources and starting work on the project. Years of experience allow us to take on such challenges. Whether you need to update, rebuild or adjust the system we’ll be happy to help you.
Book a call with a MobiDev representative in the USA, Canada, the UK, or the European Union!