If you are running PHP 5.6 or an early 7.x release, you are on an unsupported version with no security patches, and the gap between where you are and where you need to be grows every year. The good news: migrating to a modern, supported PHP is a solved problem when you do it incrementally. The bad news: teams keep attempting it as a big-bang rewrite and get burned.
This guide is the field-tested path: the one that keeps your application running while you modernise it.
Why this matters now
- Security. Unsupported PHP receives no security fixes. Known vulnerabilities simply stay open.
- Compatibility. Libraries, payment SDKs, and hosting platforms drop support for old versions. Eventually you cannot install the thing you need.
- Hiring and cost. Fewer developers want to work on a dead version, and everything takes longer on an ageing stack.
- Performance. Modern PHP is dramatically faster than 5.6. The upgrade often pays for itself in reduced server load alone.
Migrate, do not rewrite
The instinct to "just rewrite it properly" is almost always wrong. A rewrite throws away years of accumulated business logic and edge-case fixes, and it cannot ship until it is finished, so you carry all the risk with no value delivered until the very end.
The strangler pattern is the safer path: you modernise the application module by module on a running system, gradually replacing old code until the legacy parts are gone. Each step ships. Each step is reversible. You are never betting the business on a single cutover.
The safe migration sequence
1. Fix compatibility where you are
Before changing versions, get the codebase into a state that could run on a newer version. Remove functions that were deleted (each(), create_function()), fix reliance on removed extensions, and clean up the patterns that newer versions reject. Tools like PHPCompatibility flag most of this automatically.
2. Add tests around what matters
You do not need 100% coverage. You need tests around the flows that would hurt if they broke: authentication, billing, checkout, anything that touches money or data integrity. These tests are your safety net for every step that follows.
3. Move up one major version at a time
Go 5.6 → 7.4 → 8.x, not 5.6 → 8.x in one leap. Each hop has a manageable set of breaking changes. Jumping the whole distance at once stacks every breakage into one debugging session.
4. Use feature flags and a parallel run
Deploy migrated modules behind flags so you can switch them on gradually and roll back instantly. For critical systems, run the new and old paths in parallel and compare outputs before cutting over. This is how you migrate with zero downtime.
5. Clean the schema while you are in there
Legacy apps accumulate unused columns and redundant indexes. A migration is a natural, low-risk moment to remove them through incremental, zero-downtime database migrations, provided you do it as its own tracked step, not a surprise.
What tends to break
- Removed functions: each(), create_function(), and old mysql_* calls.
- Stricter typing: code that relied on loose type juggling and implicit conversions.
- Error handling: many recoverable errors became exceptions; silent failures now surface loudly.
- Array and string internals: curly-brace access, changes to how certain built-ins handle edge cases.
- Old dependencies: ancient framework and library versions are frequently the hardest part, not your own code.
How long it takes
It depends on size and test coverage, but as a rough guide: a small-to-medium application with reasonable structure is often a few weeks; a large monolith with no tests and old dependencies can run to a few months. The variable that moves this most is not the PHP version: it is how tangled the dependencies are and how much of the behaviour is currently untested.
The cost of waiting
Every year on an unsupported version, the migration gets harder: more dependencies fall out of support, more code accumulates on the old assumptions, and the eventual jump gets longer. The cheapest time to migrate was when your version went end-of-life. The second cheapest is now.
We migrate legacy PHP applications to modern, supported versions using exactly this approach: incremental, tested, zero-downtime. See how we approach web engineering, read the SaaS platform migration reference build, or book a call to talk through your codebase.