Getting ready for PHP 8.4: some code changes landing in 6.7

Earlier in the 6.7 cycle, @hellofromtonya and @jrf made a number of commits to get the codebase ready for PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher 8.4.

Here are a few of the most notable, starting with PR #7376:

Fix trigger_error() with E_USER_ERROR deprecation in wp_trigger_error().

PHP 8.4 deprecates the use of trigger_errror() with E_USER_ERROR as the error level, because this way of creating a Fatal Error brings its own set of pitfalls (finally blocks not executing, destructors not executing). instead, the recommendation is to use an exception or do a hard exit.

WP has its own wp_trigger_error() function, which under the hood calls trigger_error(). If the WP version of the function passes E_USER_ERROR as the $error_level, it too will hit the PHP 8.4 deprecation.

Now, there were basically three options:

  • Silence the deprecation until PHP 9.0 and solve this properly then. But that wouldn’t even really buy time, let alone solve the problem. That’s because before PHP 8.0, error silencing goes too far, applying to all errors. And starting with PHP 8.0, silencing doesn’t apply to fatal errors.
  • Use exit($status) when wp_trigger_error() is called with E_USER_ERROR. But that would make the code untestable. It would also disable handling of these errors with custom error handlers. Neither of those are acceptable outcomes.
  • Throw an exception when wp_trigger_error() is called with E_USER_ERROR. This is a fairly elegant solution, and it carries the least BC-breaking impact. There is some chance the error gets caught in a try-catch, but that’s not actually a bad thing. It’s likely to only happen for errors that can be worked around—and that’s actually an unexpected bonus.

This commit implements the third option, which:

  • Introduces a new WP_Exception class.
  • Starts using WP_Exception in the wp_trigger_error() function when the $error_level is set to E_USER_ERROR.

This change is covered by pre-existing tests, which have been updated to expect the exception instead of a PHP error.

Why not use WP_Error?

Well, for one, this would lead to completely different behavior (BC).

WP_Error doesn’t extend Exception. So the program would not stop. Instead, it would keep running, which is a much bigger breaking change and carries security risks. WP_Error also doesn’t natively trigger displaying/logging of the error message, so it would still need an exit with the error message, bringing us back to point 2 above.

Introducing WP_Exception delivers (essentially) the same behavior. It retains the fatal error and error message displaying/logging behaviors. Plus it introduces a base Exception class, which future exception classes can extend over time.

References:

Follow-up to [56530].

Several other commits, from #62061, also help get the codebase ready for 8.4. You can find them after an exhaustive introduction to the changes coming to the new PHP.

Here’s the list, by GH pull request:

PR #7369 WP_HTML_Processor: fix implicitly nullable parameter [1] in the WP_HTML_Processor class.

PR #7370 fixes the deprecation of  xml_set_object() for the TestXMLParser helper utility.

PR #7371 fixes the same deprecation for the IXR_Message::parse() method.

PR #7372  fixes the deprecation for the AtomParser::parse() method.

PR #7373 fixes it for the  MagpieRSS::__construct() method.

PR #7374 replaces the call to the deprecated mysqli_ping() with the DO 1 query.

PR #7375 adds a simple test for the Text_Diff::_check() method—and fixes the bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. that test finds!

PR #7377 adds testing for PR #7376.

PR #7379 Build/Test Tools: Enable running all the tests on PHP 8.4 once there’s a stable release of Xdebug 3.4.0.

Props @hellofromtonya for the commit message that formed the basis of this dev notedev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase. and to @peterwilsoncc for review and collaboration.

#6-7, #dev-notes, #field-guide