← Back to all posts
September 6, 2026
•

PHP Version Compatibility Fix for WordPress: Upgrading to PHP 8 Without Downtime

PHP code on a laptop screen in a dark workspace, illustrating a PHP version compatibility fix for WordPress

The email from the host is polite and firm: PHP 7.4 (or 8.0) is end of life, your site will be moved to PHP 8.2 on a given date, please make sure you are compatible. Then someone clicks the switch early, the homepage turns white, and the emergency starts. The PHP version compatibility fix WordPress sites need is rarely one big change. It is a hundred small ones spread across ten-year-old plugins, a custom theme somebody wrote in 2016 and a handful of libraries bundled inside plugins, and the work is in finding them before your visitors do.

This is the process we follow on our PHP version compatibility fix service, written for a site owner or technical lead who has received that email and needs a plan. The goal is an upgrade with zero downtime: audit, fix, test on a copy running the target PHP version, switch with a rollback ready, then clean up. Every command below is one we run on client sites.

why PHP 8 breaks WordPress sites that ran fine on 7.4

PHP 8.0, 8.1 and 8.2 each removed or tightened things that older WordPress code relied on. The ones we hit most often:

  • create_function() and each() were removed in 8.0. Old themes and plugins used both, especially in widget and shortcode code.
  • Internal functions now throw a TypeError instead of a warning when passed the wrong type. count( null ), strlen( [] ) and implode() with reversed arguments turn from noise into fatal errors.
  • Passing null to non-nullable internal parameters is deprecated in 8.1, so strlen( $undefined ) and trim( get_option( 'missing' ) ) fill the error log.
  • Dynamic properties are deprecated in 8.2. Any class that sets $this->foo without declaring it logs a notice on every request; in 9.0 it will be an error.
  • A required parameter after an optional one is deprecated. Older plugin function signatures do this constantly.
  • Extensions that no longer exist: mcrypt is gone, and plugins that bundled an old PHPMailer, Guzzle or PHPExcel fail on their own.

WordPress core itself has supported PHP 8.x for several releases, so a current core install is not the issue. The issue is everything around it.

step 1: audit before you change anything

Start with an inventory. You cannot fix what you have not listed, and you will find plugins that have not been updated since PHP 5 was current:

wp core version
wp plugin list --fields=name,status,version,update_version,auto_update
wp theme list --fields=name,status,version,update_version

# Which PHP version is the site on now, and which extensions does it load?
wp eval 'echo PHP_VERSION . PHP_EOL; echo implode(", ", get_loaded_extensions());'

Update everything that has an update available and note anything with no update in more than two years; those are your likely problems. Then run static analysis with PHPCompatibilityWP, which understands WordPress polyfills and flags real issues rather than every WordPress function:

composer require --dev phpcompatibility/phpcompatibility-wp 
  dealerdirect/phpcodesniffer-composer-installer

vendor/bin/phpcs -p --standard=PHPCompatibilityWP 
  --runtime-set testVersion 8.2- 
  --extensions=php --ignore='*/vendor/*,*/node_modules/*' 
  --report=summary wp-content/plugins wp-content/themes wp-content/mu-plugins

The summary report gives you a count of errors and warnings per file. Errors are things that will fatal on the target version; warnings are deprecations that will fill the log now and break later. Sort by errors, and for each plugin decide: update, replace, or patch.

step 2: reproduce on a staging copy with the target PHP

Static analysis misses runtime behaviour, so build a copy of the site running the target version. Most hosts (Cloudways, Kinsta, WP Engine, SiteGround) provide a staging environment with a per-site PHP selector; on a VPS or AWS, spin up a second PHP-FPM pool or a Docker container with the target version and point a staging hostname at it. Then turn logging on in the staging wp-config.php and walk every critical path:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/var/log/wp/staging-debug.log' );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', false );

Critical paths means the homepage, one of each post type, search, the contact form submission, login, the admin post editor, the plugin settings screens, cron (wp cron event run --due-now) and, for stores, the full checkout including the payment gateway in test mode and the order emails. Tail the log while you do it. A warm PHP 8.2 run of a site that was clean on 7.4 will typically produce dozens of distinct deprecation lines from three or four sources; that list is your work order.

step 3: the PHP version compatibility fix WordPress checklist

With the list in hand, the fixes themselves are mostly mechanical. The patterns below account for the majority of what we patch.

fatal errors first

// Before (removed in PHP 8)
add_filter( 'the_title', create_function( '$t', 'return strtoupper($t);' ) );
while ( list( $key, $val ) = each( $items ) ) { /* ... */ }

// After
add_filter( 'the_title', fn( $t ) => strtoupper( $t ) );
foreach ( $items as $key => $val ) { /* ... */ }

// Before: TypeError on PHP 8 when $terms is a WP_Error or null
$count = count( $terms );
// After
$count = is_array( $terms ) ? count( $terms ) : 0;

deprecations that will become fatal

// Null to non-nullable parameter (8.1)
$len = strlen( $value ?? '' );

// Dynamic property (8.2): declare it, or allow it on legacy classes
class Legacy_Widget extends WP_Widget {
    public $settings = [];
}
#[AllowDynamicProperties]
class Third_Party_Thing { /* untouched vendor class */ }

// Required parameter after optional (8.0)
function render_card( $title = '', $id ) {}        // before
function render_card( $title, $id ) {}             // after, with callers updated

libraries bundled inside plugins

Plugins that vendor their own copy of PHPMailer, Guzzle, TCPDF or a payment SDK need the library updated, not the plugin code. Check composer.json inside the plugin directory, update the dependency on the target PHP version and rebuild the vendor/ folder. If the plugin is abandoned, that is often the moment to replace it.

abandoned plugins: replace, fork or shim

When a plugin has no maintainer, you have three options in order of preference. Replace it with a maintained alternative and migrate the data. Fork it into a private repository, patch it, and treat it as your own code from now on. Or, for a single offending function, add an mu-plugin that removes the broken hook and re-adds a fixed version. Shims are quick but they are debt; write down what they cover.

step 4: switch without downtime

Once staging runs clean on the target version, the production switch should be boring. The mechanism depends on the stack, but the principle is the same: keep the old PHP runtime available and change only the routing.

  • cPanel or Plesk: MultiPHP Manager or the PHP selector changes the handler per domain. Switching back takes the same thirty seconds.
  • Managed hosts: the dashboard PHP selector, usually applied within a minute, with the previous version one click away.
  • Nginx and PHP-FPM on a VPS or EC2: install the new PHP version alongside the old one, create a pool for it, and switch the socket in the server block.
# /etc/nginx/sites-available/example.com
location ~ .php$ {
    include snippets/fastcgi-php.conf;
    # fastcgi_pass unix:/run/php/php7.4-fpm.sock;   # old, keep the service running
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;     # new
}

sudo nginx -t && sudo systemctl reload nginx
sudo tail -f /var/log/php8.2-fpm.log /var/log/wp/debug.log

Do the switch at a low-traffic hour with the error logs open, run the same critical path checklist against production, and keep the old pool running for a week. Rollback is one line in the config and a reload. This is the same discipline we use when moving sites to new infrastructure in our AWS migration work, and it is why “without downtime” is achievable rather than a marketing phrase.

step 5: after the switch

PHP 8 is faster than 7.4 on the same hardware, and OPcache settings decide how much of that you get. Set opcache.memory_consumption to at least 192 MB on a site with a large plugin set, opcache.max_accelerated_files to 20000 or more, and leave opcache.validate_timestamps on unless you have a deploy step that resets the cache. Verify nothing was altered during the emergency with wp core verify-checksums and wp plugin verify-checksums --all.

Two follow-ups are worth scheduling. Sites that have been avoiding a PHP upgrade for years usually have a database that has been neglected for just as long, and the cleanup in our WordPress database optimization checklist compounds the speed gain from the new runtime. And an unsupported PHP version is a security problem in its own right: a large share of the compromised sites we handle were running PHP that stopped receiving security patches long before the breach. If you suspect that has already happened, our hacked WordPress site recovery process explains what a clean-up involves, and the hacked site recovery service is the fast route.

when to do this yourself vs hire someone

If the audit shows a handful of warnings in actively maintained plugins, update them, test on staging and switch; you do not need us. Hire when the PHPCompatibilityWP report shows errors in a custom theme or in plugins with no update, when the site is a store or membership site where a broken checkout costs money by the hour, or when there is no staging environment and the host has given you a deadline. A PHP version compatibility fix WordPress engagement with us typically runs three to ten working days depending on how much abandoned code is involved, and ends with the site on a supported version, a written list of everything patched, and a rollback that was tested rather than assumed. Ongoing version management afterwards is part of our website maintenance and support plans.

get the upgrade done before the deadline

Send us your current PHP version, the target version, your host and the plugin list output from step one through our contact page. Within 24 hours you will have a fixed scope and fixed price in writing for a PHP version compatibility fix WordPress owners can rely on, from the engineers who will do the work, with no downtime during the switch.

Share this post

keep reading

Portable external hard drive connected to a laptop, illustrating an automated WordPress backup system
September 22, 2026
•

Automated WordPress Backup System Setup: Offsite, Versioned and Actually Tested

Automated WordPress backup system setup done properly: offsite S3 storage, versioned retention, write-only credentials, hourly store backups, tested restores.

Read more
Page speed test results on a monitor, illustrating Core Web Vitals optimization for WordPress
September 20, 2026
•

Core Web Vitals Optimization for WordPress: LCP, INP and CLS Fixes That Actually Work

Core Web Vitals optimization for WordPress, metric by metric: the LCP, INP and CLS fixes in theme, plugins and server that move…

Read more
Glass cloud icon with data layers above a padlock, illustrating AWS hosting migration for WordPress
September 18, 2026
•

AWS Hosting Migration for WordPress: Lightsail vs EC2 vs Managed Hosting

AWS hosting migration for WordPress compared: Lightsail vs EC2 with RDS vs managed hosting, the migration steps we run, and what breaks…

Read more

want this kind of thinking on your project?

Tell us what you are building and we'll come back with a straight answer on scope, timeline and cost within 24 hours.
start a project