You've decided not to rewrite. Good. Now you have to modernize an application that's live, earning money and full of code nobody's read in years, without telling your customers to wait six months while you do it.
That's the part nobody writes about. Here's the order we work in, and why the order matters more than the tools.
Get onto a supported version first
Before any refactoring, before any framework work, move to a supported PHP release. Unsupported versions get no security patches, which turns every newly disclosed vulnerability into your problem alone.
This step also tends to pay for itself. Newer PHP is meaningfully faster than what you're running, so an upgrade you did for security reasons shows up as lower server bills and quicker pages.
Next, put tests around the parts that touch money, customer data and login. Not full coverage, that comes later. Just enough that you'll know within minutes if a change broke something you can't afford to break.
Then add static analysis and let it fail your build. PHPStan catches the null and type errors your tests won't, and Rector applies deprecation fixes mechanically, which turns the next version bump into a pull request rather than a project.
Only now do you start replacing code. The trick is to replace it from the outside in, one route at a time.
Pick a single page or endpoint, ideally one that matters but isn't the checkout. Build its replacement properly, put it behind the same URL, and send real traffic to it. Watch it for a week with actual users on it, then move to the next one. The old application keeps serving everything you haven't migrated yet, so nothing has to be finished before anything can ship. Six months in you have a system that's half new and fully working, and you never asked anyone to stop delivering features while it happened.
Some modules will resist. Anything with business logic buried in a stored procedure or a template takes longer, and that's fine: you've found the real complexity, which a rewrite plan would have discovered much later and much more expensively.
Nothing ships if everything has to ship at once
The dull order is the fast order
Version, tests, analysis, then replacement. Each step makes the next one cheaper and safer, which is why we don't reorder it. You can see the tools we use at each stage, or how we add PHP engineers to a team already mid migration.
Modernization isn't one decision, it's a sequence of small ones you're allowed to stop after any of. That's the whole advantage. A rewrite gives you one enormous bet, and this gives you thirty small ones you can win separately.
If your application is stuck on an old version and the roadmap won't wait, that's the normal starting point rather than a failure. Our PHP engineering work mostly looks like this: unglamorous sequencing that keeps you shipping.