WordPress and PHP 8.3: what changes for plugins and themes

By CompatNav · Published · Last reviewed · 8 min read

Short answer

WordPress 6.4 and later work with PHP 8.3; your plugins and theme decide whether your site does. Of the PHP 8.3 changes you’re most likely to meet in plugins and themes, most only log deprecation notices, and the code keeps working. What can stop code depends on values while the site runs, for example an invalid date given to DateTime::modify(), which no code check can see in advance. php.net lists the full set of changes. PHP 8.3 gets security fixes until 31 December 2027.

Is WordPress ready for PHP 8.3?

PHP 8.3.0 was released on 23 November 2023. Its active support ended on 31 December 2025; it gets security fixes until 31 December 2027 (php.net).

The WordPress core team’s compatibility page lists WordPress 6.4 and later as compatible with PHP 8.3. That covers WordPress itself; the changes below concern the code of your plugins and theme.

The short version

The PHP 8.3 changes you’re most likely to meet in plugins and themes. php.net lists the full set of backward incompatible changes and deprecated features.

What changes in PHP 8.3What happensKind
DateTime::modify() with a date it can’t readAn exception instead of a warning: the page stops unless the code catches itDepends on values
A negative index in an empty arrayThe next index continues from it instead of starting at 0Silent change
get_class() without arguments, assert_options(), ASSERT_* and MT_RAND_PHP constants, changed return types of built-in methodsDeprecation notice, code keeps workingNotices
++ on an empty or non-alphanumeric stringDeprecation notice, depends on valuesNotices

What can stop the code: only with some values

Of the PHP 8.3 changes you’re most likely to meet in plugins and themes, none stops code in every case. One can, depending on the values it gets. php.net’s changelog for DateTime::modify(): “DateTime::modify() now throws DateMalformedStringException if an invalid string is passed. Previously, it returned false, and a warning was emitted.” (php.net)

So a date a visitor typed, or a setting left in an odd format, used to give a warning and let the plugin carry on; on PHP 8.3 it stops the page unless the plugin catches the exception:

wp-content/plugins/event-calendar/includes/reminders.php

<?php
$reminder = new DateTime('2026-05-01');
$result = $reminder->modify('next thursday-ish'); // a date a visitor typed

echo $result ? $result->format('j F Y') : 'Not a valid date', "\n";

Output on PHP 8.2.34

Warning: DateTime::modify(): Failed to parse time string (next thursday-ish) at position 13 (-): Unexpected character in /var/www/html/wp-content/plugins/event-calendar/includes/reminders.php on line 3
Not a valid date

Output on PHP 8.3.35the script stopped

Fatal error: Uncaught DateMalformedStringException: DateTime::modify(): Failed to parse time string (next thursday-ish) at position 13 (-): Unexpected character in /var/www/html/wp-content/plugins/event-calendar/includes/reminders.php:3
Stack trace:
#0 /var/www/html/wp-content/plugins/event-calendar/includes/reminders.php(3): DateTime->modify('next thursday-i...')
#1 {main}
  thrown in /var/www/html/wp-content/plugins/event-calendar/includes/reminders.php on line 3

Code: catching the exceptionCode that catches the exception handles both versions; PHP 8.2 still writes its warning:

wp-content/plugins/event-calendar/includes/reminders.php

<?php
$reminder = new DateTime('2026-05-01');
try {
    $result = $reminder->modify('next thursday-ish'); // a date a visitor typed
} catch (Exception $e) { // PHP 8.3 and later throw here
    $result = false;
}

echo $result ? $result->format('j F Y') : 'Not a valid date', "\n";

Output on PHP 8.2.34

Warning: DateTime::modify(): Failed to parse time string (next thursday-ish) at position 13 (-): Unexpected character in /var/www/html/wp-content/plugins/event-calendar/includes/reminders.php on line 4
Not a valid date

Output on PHP 8.3.35

Not a valid date

No code check can tell in advance which dates a site will pass, so watch your error log after switching.

A silent change: negative array indexes

“Assigning a negative index $n to an empty array will now make sure that the next index is $n+1 instead of 0.” (php.net) No notice, no error; only the keys change:

wp-content/plugins/member-list/includes/ranking.php

<?php
$ranking = [];
$ranking[-3] = 'Guest';
$ranking[] = 'Adam';
$ranking[] = 'Sara';

echo implode(', ', array_keys($ranking)), "\n";

Output on PHP 8.2.34

-3, 0, 1

Output on PHP 8.3.35

-3, -2, -1

Code that relies on the old numbering (for example, looking for the first item at index 0) gets a different result without any message.

What only shows notices: the deprecations you’re most likely to meet

A deprecation notice means: this still works, but a future PHP version is expected to change it. The page is built as usual. PHP 8.3 deprecates more than these; php.net lists the full set in its deprecated features in PHP 8.3.

get_class() without arguments

“Calling get_class() and get_parent_class() without arguments is now deprecated.” (php.net) The fix, with tested code, is in PHP 8.2 reaches end of life: self::class inside the class.

assert_options() and the ASSERT_* constants

“The assert_options() function is now deprecated. The ASSERT_ACTIVE, ASSERT_BAIL, ASSERT_CALLBACK, ASSERT_EXCEPTION, and ASSERT_WARNING constants have been deprecated.” (php.net) A line using both gets two notices; PHP 8.5 words them differently:

wp-content/plugins/dev-checks/dev-checks.php

<?php
if (assert_options(ASSERT_ACTIVE)) {
    echo "Assertions are on\n";
}

Output on PHP 8.2.34

Assertions are on

Output on PHP 8.3.35

Deprecated: Constant ASSERT_ACTIVE is deprecated in /var/www/html/wp-content/plugins/dev-checks/dev-checks.php on line 2

Deprecated: Function assert_options() is deprecated in /var/www/html/wp-content/plugins/dev-checks/dev-checks.php on line 2
Assertions are on

Output on PHP 8.5.11

Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in /var/www/html/wp-content/plugins/dev-checks/dev-checks.php on line 2

Deprecated: Function assert_options() is deprecated since 8.3 in /var/www/html/wp-content/plugins/dev-checks/dev-checks.php on line 2
Assertions are on

This is how a check reports it:

Code: reading the setting with ini_get()

wp-content/plugins/dev-checks/dev-checks.php

<?php
if (ini_get('assert.active')) {
    echo "Assertions are on\n";
}

Output on PHP 8.2.34

Assertions are on

Output on PHP 8.5.11

Assertions are on

MT_RAND_PHP

“The MT_RAND_PHP Mt19937 variant is deprecated.” (php.net) Worth knowing before fixing it: the default variant gives a different sequence of numbers for the same seed, so a plugin that relied on a fixed “random” order shows a different one.

Code: before and after (note the different number)

wp-content/plugins/daily-quote/daily-quote.php

<?php
mt_srand(42, MT_RAND_PHP); // the same "random" quote for everyone today
echo 'Quote number ', mt_rand(1, 100), "\n";

Output on PHP 8.2.34

Quote number 64

Output on PHP 8.3.35

Deprecated: Constant MT_RAND_PHP is deprecated in /var/www/html/wp-content/plugins/daily-quote/daily-quote.php on line 2

Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in /var/www/html/wp-content/plugins/daily-quote/daily-quote.php on line 2
Quote number 64

Output on PHP 8.5.11

Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in /var/www/html/wp-content/plugins/daily-quote/daily-quote.php on line 2

Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in /var/www/html/wp-content/plugins/daily-quote/daily-quote.php on line 2
Quote number 64

wp-content/plugins/daily-quote/daily-quote.php

<?php
mt_srand(42); // the same "random" quote for everyone today
echo 'Quote number ', mt_rand(1, 100), "\n";

Output on PHP 8.2.34

Quote number 43

Output on PHP 8.5.11

Quote number 43

Changed return types of built-in methods

A plugin class that extends a PHP class and overrides one of its methods must promise a compatible return type. PHP 8.3 narrowed some, for example ArrayObject::asort(), which now returns true; an override that still promises bool gets a notice:

Code: before and after

wp-content/plugins/member-list/includes/class-sorted-list.php

<?php
class Sorted_List extends ArrayObject {
    public function asort(int $flags = SORT_REGULAR): bool {
        return parent::asort($flags);
    }
}

$list = new Sorted_List(['b' => 'Sara', 'a' => 'Adam']);
$list->asort();
echo implode(', ', (array) $list), "\n";

Output on PHP 8.2.34

Adam, Sara

Output on PHP 8.3.35

Deprecated: Return type of Sorted_List::asort(int $flags = SORT_REGULAR): bool should either be compatible with ArrayObject::asort(int $flags = SORT_REGULAR): true, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/html/wp-content/plugins/member-list/includes/class-sorted-list.php on line 3
Adam, Sara
The fixed override promises true, like the method it overrides; it runs without a notice on PHP 8.2, 8.3 and 8.5:

wp-content/plugins/member-list/includes/class-sorted-list.php

<?php
class Sorted_List extends ArrayObject {
    public function asort(int $flags = SORT_REGULAR): true {
        return parent::asort($flags);
    }
}

$list = new Sorted_List(['b' => 'Sara', 'a' => 'Adam']);
$list->asort();
echo implode(', ', (array) $list), "\n";

Output on PHP 8.2.34

Adam, Sara

Output on PHP 8.3.35

Adam, Sara

Output on PHP 8.5.11

Adam, Sara

++ on empty or non-alphanumeric strings

“Using the increment operator (++) on empty, non-numeric, or non-alphanumeric strings is now deprecated.” (php.net) Whether it happens depends on the string’s value at run time; PHP 8.5 words the message differently:

Code: incrementing an empty string

wp-content/plugins/member-list/includes/codes.php

<?php
$code = ''; // no code saved yet
$code++;
var_dump($code);

Output on PHP 8.2.34

string(1) "1"

Output on PHP 8.3.35

Deprecated: Increment on non-alphanumeric string is deprecated in /var/www/html/wp-content/plugins/member-list/includes/codes.php on line 3
string(1) "1"

Output on PHP 8.5.11

Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in /var/www/html/wp-content/plugins/member-list/includes/codes.php on line 3
string(1) "1"

How to check your site before switching

  1. Find your current PHP version: Tools → Site Health → Info → Server.
  2. Check your plugins and theme for PHP 8.3. With CompatNav, choose PHP 8.3 next to Check readiness for and start a scan. It finds the deprecated functions, constants and return types above; the date and array changes depend on values and don’t show up in any code check.
  3. Fix what will break before you switch; notices can wait for the plugins’ next updates.
  4. Switch, then watch your important pages and your error log for a few days.

A newer version gives you more time before the next upgrade: WordPress and PHP 8.4 and WordPress and PHP 8.5 list what changes there.

Key takeaways

  • PHP 8.3 was released on 23 November 2023; its active support ended on 31 December 2025, and it gets security fixes until 31 December 2027 (php.net). WordPress 6.4 and later are compatible with it.
  • Of the changes you’re most likely to meet in plugins and themes, most only add deprecation notices: get_class() without arguments, assert_options(), MT_RAND_PHP, changed return types of built-in methods.
  • What can stop code depends on values: an invalid date string now throws an exception in DateTime::modify() instead of a warning.
  • One change is silent: after a negative index in an empty array, the next index continues from it instead of starting at 0.
  • Check your plugins and theme before switching, and watch the error log after: no code check sees problems that depend on values.

Frequently asked questions

Is PHP 8.3 still supported?

Yes, with security fixes only: its active support ended on 31 December 2025, and security fixes continue until 31 December 2027 (php.net). PHP 8.4 and 8.5 are supported for longer.

PHP 8.3 or a newer version?

If your plugins and theme are ready for a newer version and your host offers it, the newer one gives you more time: PHP 8.4 gets security fixes until 31 December 2028, PHP 8.5 until 31 December 2029. PHP 8.3 is the smaller step from 8.1 or 8.2.

Is WordPress compatible with PHP 8.3?

Yes. The WordPress core team’s compatibility page lists WordPress 6.4 and later as compatible with PHP 8.3. Your plugins and theme are a separate question.

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.