[ Development  /  6 min read ]

How to Upgrade an Old PHP Application or CMS to PHP 8: WordPress, Laravel, OpenCart and Magento Without Breaking Production

[ Short answer ]

To upgrade an old PHP application or CMS to PHP 8 safely: clone the site to staging, switch only the staging copy to the target PHP version (8.3 or 8.4 for most stacks), run a compatibility scan (PHPCompatibility, Rector), fix what breaks — usually removed functions, stricter type errors, dynamic properties and abandoned plugins or extensions — test the money paths, then switch production per-domain. The PHP2Shell RCE disclosed in October 2026 made this urgent: end-of-life PHP versions (8.1 and older) no longer receive security fixes at all.

Every old PHP site has a reason it is still on PHP 7.4 or 8.1: a theme that white-screens on anything newer, an extension whose developer disappeared, a codebase nobody wants to touch. That trade-off just changed. The PHP2Shell vulnerabilities disclosed on 21 October 2026 (CVE-2026-109618 and CVE-2026-109619) are critical unauthenticated remote code execution flaws affecting PHP 5.4 through 8.5.11 — and only PHP 8.2, 8.3, 8.4 and 8.5 received patches. If your site runs PHP 8.1 or older, it is now exposed to a known, actively probed RCE that will never be fixed on that version.

So this guide is about the real job: not clicking the version switcher, but making an old application or CMS actually compatible with a current PHP version. It is the process I use on client sites — WordPress, Laravel, OpenCart, Magento and custom PHP apps — on WHM/cPanel servers and AWS VPS instances, without breaking production along the way.

Step 1: Pick the right target version

Do not automatically jump to the newest release. The right target is the newest version your entire stack supports:

  • PHP 8.3 or 8.4 is the sweet spot for most sites in late 2026: both are patched against PHP2Shell, both have years of security support left, and CMS plugin and extension ecosystems have had time to catch up.
  • PHP 8.5 is current and fine for modern codebases, but the long tail of WordPress plugins and OpenCart extensions is tested against it least.
  • PHP 8.2 is patched but close to the end of its security window — a reasonable stepping stone for a very old codebase, not a destination.

Check the version your framework or platform officially supports first: current WordPress runs well on 8.3/8.4; recent Laravel releases require PHP 8.2+; Magento 2.4.7+ supports 8.2/8.3 and newer releases add 8.4; OpenCart 4 requires PHP 8 while OpenCart 3 was built for 7.x. Those constraints decide more than preference does.

What actually breaks between PHP 7.x and 8.x

Knowing the failure patterns makes the compatibility scan much faster to interpret. The big ones I fix again and again:

  • Warnings became fatal TypeErrors. Passing null or the wrong type to many built-in functions, or calling a method on null, now throws instead of limping on. Code that "worked" on 7.x by ignoring warnings dies on 8.x.
  • Removed functions and extensions. create_function(), each(), money_format(), curly-brace string offsets and the old mysql_* extension (gone since 7.0, still common in PHP 5-era code) all hard-fail.
  • Dynamic properties are deprecated (8.2+). Writing $obj->someNewProp on a class that never declared it floods logs with deprecations and breaks code that treats objects as ad-hoc containers. Legacy CMS extensions do this constantly.
  • Stricter comparisons and string/number juggling (8.0). 0 == "foo" changed its answer; code relying on loose comparisons in auth checks or option handling can change behavior silently — the worst kind of break.
  • Old libraries pinned to old PHP. Composer dependencies with "php": "^7.2" constraints, abandoned WordPress plugins last updated in 2019, OpenCart OCMOD patches against files that moved. The library, not your code, is often the real blocker.

WordPress on PHP 8: plugins are the problem, not core

WordPress core has been reliable on PHP 8.x for years; nearly every "critical error" after a PHP switch traces to a plugin or theme. The method:

  1. Clone the site to staging and switch the clone to the target PHP version.
  2. Turn on debug logging (WP_DEBUG_LOG) and click through the site, admin, forms and checkout. The log names the guilty plugin directly in each stack trace.
  3. Update every plugin and theme first — most compatibility work was already done upstream. For each one that still fails: find a maintained replacement, or patch it if it is small and local to your site.
  4. Watch deprecation notices too: a plugin spraying dynamic-property deprecations on 8.3 is telling you it is unmaintained and will fail harder later.

A white screen or "there has been a critical error" page after switching is almost always one fatal in one plugin, and it is diagnosable in minutes from the log — the exact workflow of my WordPress bug fixing service. If the site matters, pair the PHP upgrade with the basics in my WordPress security checklist while you are in there.

Laravel: climb the framework ladder, not just the PHP version

Laravel pins its PHP support per major version, so an app on Laravel 6 or 8 usually cannot run modern PHP until the framework moves. The upgrade is therefore a ladder: raise Laravel one or two majors at a time (following each version's upgrade guide), raising PHP alongside until you reach a current Laravel on PHP 8.3/8.4. In practice:

  • composer outdated and the php constraint in composer.json tell you where you stand; abandoned packages are the usual blockers, and each needs a maintained fork or replacement.
  • Rector automates a surprising share of the mechanical changes (constructor property promotion aside, it handles removed-function rewrites, nullable types and framework-specific sets).
  • A test suite, even a thin one covering login, the main workflows and payments, turns the upgrade from gambling into engineering. If there are no tests, writing those few first is the cheapest insurance available.

Old Laravel apps are a core part of my Laravel development service: version-ladder upgrades, dependency replacement and getting a test harness around code that never had one.

OpenCart and Magento: the PHP version is tied to the platform version

For both carts, PHP compatibility and platform version are the same decision. OpenCart 3.x was built for PHP 7.x — the later 3.0.4.x releases run on early PHP 8 with fixes, but the extension ecosystem is the constraint, and OCMOD-patched stores break in ways stock stores do not. The durable fix is OpenCart 4, which requires PHP 8 — and that move is a migration, which I have covered step by step in the OpenCart 4 upgrade guide. Magento is stricter still: each 2.4.x patch release documents exactly which PHP versions it supports, so you upgrade Magento and PHP together, extension by extension — the process in my Magento 2 upgrade guide. Either way, the staging-first discipline below applies doubly, because checkout and payment modules are where PHP incompatibilities cost actual revenue.

Custom and legacy PHP applications

For a custom app with no vendor to lean on, two tools do most of the discovery before anything runs:

# static compatibility scan: flags removed functions, syntax, deprecations
composer require --dev phpcompatibility/php-compatibility squizlabs/php_codesniffer
vendor/bin/phpcs -p src/ --standard=PHPCompatibility --runtime-set testVersion 8.3

# automated rewrites for the mechanical fixes
composer require --dev rector/rector
vendor/bin/rector process src/ --dry-run

The scan output is a worklist, not a verdict: static analysis catches removed syntax and functions but misses behavioral changes like comparison semantics, so runtime testing on staging is still mandatory. For PHP 5-era code (mysql_*, register_globals assumptions, no autoloading) budget for modernization rather than patching — sometimes a focused rewrite of the few scripts still in use is cheaper than dragging the whole codebase forward.

The upgrade process that does not break production

  1. Inventory. List every site on the server and its current PHP version (on WHM, MultiPHP Manager shows all domains at once). Rank by exposure and by business value.
  2. Stage. Clone each site — files and database — to a staging subdomain or a separate AWS instance. Only the clone gets the new PHP version. On WHM this is clean because PHP versions are per-domain; on a VPS, run two PHP-FPM pools (for example php8.1-fpm and php8.3-fpm) side by side and point only the staging vhost at the new pool.
  3. Scan and fix. Compatibility scan, update everything updatable, replace what is abandoned, patch what is yours.
  4. Test the money paths. Login, search, cart, checkout with a sandbox payment, order emails, admin workflows, cron jobs and queue workers — with the PHP error log open the whole time.
  5. Switch production per-domain in a low-traffic window, watch logs for 48 hours, and keep the old PHP-FPM pool installed for the first week so rollback is a one-line vhost change, not a reinstall.
  6. Remove the old version. The job is not done while an end-of-life PHP binary is still serving anything — that was the whole point.

Want it done for you?

This is work I do end to end: the server side (new PHP versions on WHM/cPanel and AWS, pools, staging environments) and the application side (WordPress, Laravel, OpenCart, Magento and custom code made compatible and tested). Small sites are often a few hours at $20/hour; a store or application with years of custom code gets an audit first and a fixed price in writing. If PHP2Shell is what brought you here, start with the patching guide for the immediate exposure, then plan the version upgrade properly — or send me a few lines about your stack and I will tell you honestly how big the job is.

Frequently asked questions

Can I just switch the PHP version in cPanel and see what happens?

On a test copy, yes — that is actually a fast way to surface failures. On production, no: a fatal error in one plugin or extension can take down the whole site, and some breakage (changed comparison behavior, silent form failures) will not announce itself. Clone to staging, switch the clone, and test with error logging on.

Which PHP version should I upgrade an old website to in 2026?

PHP 8.3 or 8.4 for most sites: both are patched against the PHP2Shell vulnerabilities, both have long security-support windows, and plugin and extension ecosystems support them well. PHP 8.2 is patched but near the end of its security life, and PHP 8.5 is the least tested by the long tail of CMS extensions.

Why does my WordPress site show a critical error after a PHP upgrade?

Almost always a single plugin or theme throwing a fatal error on the new PHP version — removed functions, strict type errors or dynamic-property use. Enable WP_DEBUG_LOG, read the last stack trace to identify the component, then update, replace or patch it. WordPress core itself runs reliably on PHP 8.x.

My Laravel app is on Laravel 7 and PHP 7.4. Can it run on PHP 8.3 directly?

No — old Laravel majors do not support current PHP, so you upgrade the framework and PHP together, one or two Laravel majors at a time, replacing abandoned Composer packages as you go. Rector automates much of the mechanical work, and a thin test suite around the critical paths makes the whole ladder far safer.

Is upgrading PHP urgent, or can it wait for a redesign?

As of October 2026 it is urgent for anything on PHP 8.1 or older: the PHP2Shell flaws (CVE-2026-109618 and CVE-2026-109619) allow unauthenticated remote code execution, exploit attempts are circulating, and end-of-life PHP versions will never receive the fix. Decouple the PHP upgrade from any redesign and do it first.

[ Want it done for you? ]

Laravel Development

APIs, dashboards and long-term maintenance of Laravel apps. Hourly work is $20/hour; defined projects get a fixed price in writing.

See the service

[ Let's talk ]

Broken, slow, or not built yet?

Describe it in a few lines and you'll get a real reply from the person who'd do the work — same working day, no discovery call required.