Upgrading WordPress from PHP 7.4 to PHP 8: what breaks, and in what order

By CompatNav · Published · Last reviewed · 5 min read

Short answer

Go straight to the version you want (PHP 8.3, 8.4 or 8.5), but check everything that changes between 7.4 and it: every step from 8.0 on applies to your plugins and theme. PHP 8.0 has by far the longest list of backward-incompatible changes, so work in that order: first what will break, starting with 8.0, then the deprecation notices. PHP 7.4 hasn’t received security fixes since 28 November 2022.

Why leave PHP 7.4

PHP 7.4 reached its end of life on 28 November 2022 (php.net): security problems found since then are not fixed by the PHP project. WordPress 7.1 still runs on PHP 7.4 (compatibility page), so the move is about your server’s safety and your plugins, not about WordPress itself.

One switch, every step in between

You don’t install PHP 8.0, then 8.1, then the next. Your host switches your site from 7.4 straight to the version you choose. But the changes of every version in between apply: code that stops on PHP 8.0 also stops on 8.5. So check for the version you want, and make sure the check covers the whole way from 7.4.

What changes at each step

The changes you’re most likely to meet in plugins and themes, version by version, with the guide that explains each:

VersionWhat can stop codeWhat only adds notices
8.0Removed functions such as create_function() and each(); code that no longer compiles and old-style constructorsAn optional parameter before a required one
8.1Writing to the whole $GLOBALS arrayPassing null to PHP functions, FILTER_SANITIZE_STRING, return types (below)
8.2–Dynamic properties
8.3An invalid date in DateTime::modify(), depending on valuesget_class() without arguments, assert_options() and more
8.4Extensions moved out of PHP, five MySQLi constantsParameters with a null default but no ?, and more
8.5setlocale() with 0, invalid attribute targets, class_alias() to reserved namesThe backtick operator, old cast names, and more

php.net’s list of backward-incompatible changes for PHP 8.0 (php.net) is about twice as long as that of any later version: 4,594 words, against 2,144 for PHP 8.4, the next longest (counted on 28 September 2026). The 8.1 one: “write access to the entire $GLOBALS array is no longer supported. For example, array_pop($GLOBALS) will result in an error.” (php.net)

PHP 8.1: “Return type of … should either be compatible with …”

One PHP 8.1 notice has no guide of its own. When a plugin class builds on one of PHP’s own classes or interfaces (here ArrayAccess, which lets an object be used like an array) and doesn’t declare return types, PHP 8.1 and later write: “Return type of … should either be compatible with …, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice”. php.net: “Most non-final internal methods now require overriding methods to declare a compatible return type, otherwise a deprecated notice is emitted during inheritance validation.” (php.net)

wp-content/plugins/site-settings/includes/class-settings.php

<?php
class Site_Settings implements ArrayAccess {
    private $values = ['colour' => 'blue'];

    public function offsetExists($key) { return isset($this->values[$key]); }
    public function offsetGet($key) { return $this->values[$key]; }
    public function offsetSet($key, $value) { $this->values[$key] = $value; }
    public function offsetUnset($key) { unset($this->values[$key]); }
}

$settings = new Site_Settings();
echo $settings['colour'], "\n";

Output on PHP 8.0.30

blue

Output on PHP 8.1.34

Deprecated: Return type of Site_Settings::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/html/wp-content/plugins/site-settings/includes/class-settings.php on line 5

Deprecated: Return type of Site_Settings::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/html/wp-content/plugins/site-settings/includes/class-settings.php on line 6

Deprecated: Return type of Site_Settings::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/html/wp-content/plugins/site-settings/includes/class-settings.php on line 7

Deprecated: Return type of Site_Settings::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/html/wp-content/plugins/site-settings/includes/class-settings.php on line 8
blue

The code keeps working; there is one notice per method, as soon as the file loads. A check that reads code finds it:

In what order to work

  1. Check for the version you want, from 7.4. CompatNav, for example, compares the version your site runs with the one you choose and lists everything in between, marked “Will break” or “Deprecation notice”. What it can’t see are changes that depend on values while the site runs, such as the invalid date on PHP 8.3; your error log shows those after the switch.
  2. Fix what will break first, oldest version first. For each item that means an update, a replacement, or a code change by the plugin’s developer.
  3. Leave the notices for the plugins’ next updates. They don’t stop your site.
  4. Switch, with a way back: a backup, and PHP 7.4 still selectable in your hosting panel for a few days.

The whole plan, step by step with a printable list, is in Is my WordPress site ready for PHP 8?.

Key takeaways

  • PHP 7.4 reached its end of life on 28 November 2022 (php.net): no security fixes since then.
  • You don’t install 8.0, 8.1 and the others one after the other, but their changes all apply: check for the version you want, from 7.4.
  • PHP 8.0 brings the most changes that can stop code: removed functions, code that no longer compiles, old constructors.
  • From PHP 8.1 on, most changes you’re likely to meet only add deprecation notices; each version still has a few that can stop code.
  • Work in order: fix what will break first, oldest version first; notices can wait for the plugins’ next updates.

Frequently asked questions

Can I skip PHP 8.0?

You can switch straight from 7.4 to, say, 8.4 in your hosting panel. What you can’t skip are 8.0’s changes: they apply on every later version too. A check for the target version covers them.

Is PHP 7.4 still safe to run?

It reached its end of life on 28 November 2022 (php.net): security problems found since then are not fixed by the PHP project. WordPress 7.1 still runs on it, but plan the move.

Which PHP 8 version should I choose?

The newest one your host offers that your plugins and theme are ready for; newer versions get security fixes for longer. The dates are in PHP 8.2 reaches end of life.

My site broke after switching. What now?

Switch back to PHP 7.4 in your hosting panel first, then find the cause: “There has been a critical error” after a PHP update shows how.

Check your own site before you upgrade

CompatNav is a free WordPress plugin. It reads the code of your plugins and themes on your own server and tells you, in plain words, what will break and what will only show notices on the PHP version you choose. It never changes your code. It can’t see problems that only appear while code runs with real data, so a quick check of your site after the upgrade still matters.

Get CompatNav on wordpress.org How it works

Sources

About the code examples: each output is the real output of the code shown, run with the official PHP builds, without a php.ini, with all errors reported and displayed. Only the file path was replaced by a neutral server path.