WordPress and PHP 8.1: what changes for plugins and themes
Short answer
WordPress 5.9 and later work with PHP 8.1, but PHP 8.1 itself reached end of life on 31 December 2025: it no longer gets security fixes. Don’t stop at 8.1; pass through it to PHP 8.3 or later. Its changes still matter on the way: one stops code (writing to the whole $GLOBALS array), and many add deprecation notices that you’ll keep seeing on every newer version: strftime(), FILTER_SANITIZE_STRING, passing null to PHP functions, the Serializable interface.
Is PHP 8.1 still a good choice?
No. php.net lists PHP 8.1 among the unsupported branches, with an end of life on 31 December 2025 (php.net). Every version that is still supported builds on it, though: a site moving from PHP 7.4 or 8.0 to 8.3 or later meets the PHP 8.1 changes on the way, so they are worth knowing.
The WordPress core team’s compatibility page lists WordPress 5.9 and later as compatible with PHP 8.1. The changes below concern the code of your plugins and theme.
The short version
The PHP 8.1 changes you’re most likely to meet in plugins and themes. php.net lists the full set of deprecated features and backward incompatible changes.
| What changes in PHP 8.1 | What happens | Kind |
|---|---|---|
Replacing the whole $GLOBALS array | Fatal error: the page stops | Stops code |
strftime(), gmstrftime(), date_sunrise() and other date functions | Deprecation notice | Notice |
FILTER_SANITIZE_STRING | Deprecation notice | Notice |
Serializable without __serialize() | Deprecation notice | Notice |
| Built-in methods overridden without return types | Deprecation notice | Notice |
null passed to a PHP function that expects text or a number | Deprecation notice, depends on values | Notice |
false turned into an array | Deprecation notice, depends on values | Notice |
The one that stops code: $GLOBALS
php.net: “write access to the entire $GLOBALS array is no longer supported.” (php.net) Writing one entry, $GLOBALS['name'] = …, still works. Replacing the array as a whole is now a fatal error, and PHP refuses the whole file:
wp-content/plugins/old-settings/old-settings.php
<?php
$GLOBALS = ['site_name' => 'My shop'];
echo 'Saved', "\n";
SavedFatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax in /var/www/html/wp-content/plugins/old-settings/old-settings.php on line 2It is rare in plugins, but when it happens the page stops, so it is the one to fix before switching.
strftime() and other date functions
strftime() formatted dates by the server’s language settings. php.net: “strftime() and gmstrftime() have been deprecated. Use date() instead (for locale-independent formatting), or IntlDateFormatter::format() (for locale-dependent formatting).” (php.net)
wp-content/plugins/event-dates/event-dates.php
<?php
$timestamp = 1798675200; // 31 December 2026, 00:00 UTC
echo strftime('%Y-%m-%d', $timestamp), "\n";
2026-12-31Deprecated: Function strftime() is deprecated in /var/www/html/wp-content/plugins/event-dates/event-dates.php on line 3
2026-12-31FILTER_SANITIZE_STRING, null and return types
Three PHP 8.1 notices are common enough to have their own guides:
- “Constant FILTER_SANITIZE_STRING is deprecated”: there is no exact replacement, so the developer chooses one.
- “Passing null to parameter … is deprecated”: depends on values, so only your error log shows it.
- “Return type of … should either be compatible …”: covered in moving from PHP 7.4 to PHP 8, with the attribute that silences it and the real fix.
The Serializable interface
Plugins that store objects, for example in a session or a cache, sometimes implement Serializable. PHP 8.1 asks for the newer methods instead:
wp-content/plugins/cart-session/cart.php
<?php
class Cart implements Serializable {
private $items = [];
public function serialize() {
return serialize($this->items);
}
public function unserialize($data) {
$this->items = unserialize($data);
}
}
echo 'Loaded', "\n";
LoadedDeprecated: Cart implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in /var/www/html/wp-content/plugins/cart-session/cart.php on line 2
LoadedThe message itself names the fix: add __serialize() and __unserialize(), alongside the old methods if the plugin still supports PHP older than 7.4.
Notices that depend on values
php.net calls it autovivification from false: “Autovivification is prohibited from scalar values, false however was an exception. This is now deprecated.” (php.net) In WordPress it happens when code reads a saved setting that doesn’t exist yet (WordPress returns false) and then adds entries to it as if it were a list:
wp-content/plugins/visit-counter/visit-counter.php
<?php
function get_saved_counts() {
return false; // like get_option() when the option doesn't exist yet
}
$counts = get_saved_counts();
$counts['home'] = 1;
echo $counts['home'], "\n";
1Deprecated: Automatic conversion of false to array is deprecated in /var/www/html/wp-content/plugins/visit-counter/visit-counter.php on line 7
1A check that reads code sees $counts['home'] = 1, not that $counts is false on your site at that moment. CompatNav doesn’t report it for that reason; your error log does. The WordPress debug log shows how to keep one without showing messages to visitors.
How to check your site
- Find your PHP version: Tools → Site Health → Info → Server, as shown in checking and changing your PHP version.
- Choose your target: 8.3 or later, not 8.1. Check plugins and theme for that version; every change on this page is part of it.
- Update what has an update, and send the rest to its developers.
- Switch, then watch the error log for the notices that depend on values.
Key takeaways
- PHP 8.1 reached end of life on 31 December 2025 (php.net): no more security fixes. Go to PHP 8.3 or later.
- WordPress 5.9 and later are compatible with PHP 8.1.
- One change stops code: replacing the whole
$GLOBALSarray is a fatal error. - Many notices start here and continue on every later version:
strftime(),FILTER_SANITIZE_STRING,Serializable, return types of built-in methods, passingnullto PHP functions. - Some notices depend on values, such as turning
falseinto an array: no code check sees them, your error log does.
Frequently asked questions
Should I use PHP 8.1 for WordPress?
No, not any more: PHP 8.1 reached end of life on 31 December 2025 and gets no security fixes. Its changes are still part of every newer version, so a site moving from PHP 7.4 or 8.0 meets them on the way to 8.3 or later.
Is WordPress compatible with PHP 8.1?
Yes. The WordPress core team’s compatibility page lists WordPress 5.9 and later as compatible with PHP 8.1. Your plugins and theme are a separate question.
Which version should I move to instead?
PHP 8.3 gets security fixes until 31 December 2027, 8.4 until 31 December 2028 and 8.5 until 31 December 2029 (php.net). wordpress.org recommends 8.3 or higher. Pick the newest one your plugins, theme and host support.
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.
Sources
- php.net: Unsupported Branches (end of life dates)
- php.net: Deprecated features in PHP 8.1.x
- php.net: Backward incompatible changes in PHP 8.1.x
- make.wordpress.org: PHP Compatibility and WordPress Versions
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.