A legacy PHP system that nobody understands is an uncomfortable thing to own. It runs the business, it’s hard to change and the developer who wrote it has moved on. The usual reaction is to propose a rewrite. Sometimes that’s right. More often it’s the most expensive of several options, and it’s chosen before anyone has looked properly at what is there.
This is what we’d check first, in roughly the order we’d check it.
1. Can you run it, and can you deploy it?
Start with the boring questions. Can a developer get the system running on a laptop from the repository alone? Is there a repository? Do you know where the production code lives, and does it match what is in version control?
On older systems the production server is the only copy of the truth. Files edited directly on the host, a config file with credentials that exist nowhere else, a cron job set up by hand. Getting the code into version control and into a repeatable deployment is the first job whatever you decide next, because every other choice depends on it.
2. What PHP version is it on, and what depends on that?
PHP releases follow a published schedule: two years of active support, then two more years where only security fixes arrive. After that a version is end of life and gets no fixes at all. If your system runs on an end-of-life version, you’re exposed to problems nobody will patch, and the hosting provider may eventually stop offering that version.
Check the version, then check what stops you upgrading it. Removed functions, changed error handling, stricter type behaviour and abandoned libraries are the usual obstacles. Some systems move up a version or two with modest effort. Others are tied to an extension or a library with no maintained successor. That distinction decides a lot of the cost.
3. Read the data model first
The database is the part of the system that matters most and changes least. The code is an opinion about it. Look at the tables, the relationships, the columns with unclear meanings and the places where rules live in the data instead of the code.
If the data model is sound and the code is messy, you have a good case for repairing in stages. If the data model itself is wrong, say a booking that can’t have more than one traveller, then no amount of tidy code fixes the real problem, and you’re looking at a migration whatever you choose.
4. Find out what is actually in use
Old systems accumulate features. Some are essential, some were used twice in 2019 and some were never finished. A rewrite that reproduces everything costs far more than one that reproduces what people use.
Ask the people who use the system, not only the owner. Look at access logs, database tables that are still being written to, and reports someone opens every month. Write a list of features in three groups: used daily, used occasionally, apparently dead. Take the dead group out of scope.
5. Find the rules nobody wrote down
This is the hidden cost of a rewrite. The old system contains years of edge-case handling: a rounding rule for one currency, a special case for a supplier, a check added after an incident. Nobody documented them, and a new system won’t have them unless someone finds them.
Techniques that help:
- Read the code around conditionals that look arbitrary. Each one has a reason.
- Read old support emails and bug reports.
- Run the old and new systems side by side on the same input and compare outputs.
- Write tests that capture what the old system does now, even where that behaviour looks odd. These are often called characterisation tests, and they give you a safety net for either repair or rewrite.
6. Check security, honestly
Look for the usual signs. Database queries built by joining strings. Passwords stored without proper hashing. File upload code that trusts the file name. Admin pages with no access control. Secrets committed in the repository. Dependencies that haven’t been updated in years.
A practical security review is part of our System Audit. It won’t find everything, and it will tell you whether the problems are fixable in place. Many are: parameterised queries and a password hash upgrade are targeted fixes, and neither needs a rewrite.
7. What does the business need that this can’t do?
A rewrite should solve a problem the current system can’t. Ask what that problem is. If the answer is "the code is ugly", that’s a maintenance cost, and probably not a reason to spend months rebuilding. If the answer is "we need a multi-currency model and the data structure can’t represent it", or "we need to open the system to partners and it has no API", that’s a structural limit, and a stronger case.
Write the requirement as a sentence the owner agrees with. If you can’t, you aren’t ready to commit.
8. Can you replace it in pieces?
The strangler pattern is the usual alternative to a full rewrite. You put a layer in front of the old system, build new features or replacement modules alongside it, and move traffic across one piece at a time. The old system shrinks until it can be switched off.
It’s slower to describe and often faster to deliver, because the business keeps running throughout and each step is small enough to test and reverse. It doesn’t suit every system. If the old code is so entangled that nothing can be separated, the pieces approach struggles. Finding that out in a short audit is cheaper than finding it halfway through.
9. What is the cost of waiting, and what is the cost of the rewrite?
Put rough numbers on both. Include the cost of running two systems during the transition, the time of your own staff for testing and the period when new features stop because everyone is busy with the migration. Be honest about the risk that a rewrite takes twice as long as planned, because that’s a common outcome.
A rewrite isn’t a bad idea. It’s a decision with a large cost that deserves evidence. If the audit says the data model is sound, the version can be upgraded and the security issues are fixable, repairing and replacing in stages is usually the better route. If it says the foundations can’t support what the business now needs, rewrite, and you’ll go in knowing why.
Our legacy modernisation service starts with the audit for exactly this reason. For the documentation you should expect at the end, see what a proper software handover contains.