WordPress and PHP 7.4

PHP 7.4 is in the final stages of its release cycle. As of the publish date of this post, version 7.4 RC3 has been released, and the final release of PHP 7.4.0 is scheduled for November 28, 2019.

As the expected changes in PHP 7.4 were made public earlier this year, contributors to WordPress Core worked to identify compatibility issues within the code base. Overall, the changes needed to declare full PHP 7.4 support were minor, and have all been made.

WordPress aims to fully support PHP 7.4 in the 5.3 release (currently scheduled for November 12, 2019).

Here is a breakdown of the changes in PHP 7.4 that plugin and theme developers need to be aware of and should accommodate in their code.

Changes to Curly Brace Syntax

In the past, PHP has allowed the use of curly braces ({}) to access array elements and string offsets.

<?php
$array = [1, 2];
echo $array[1]; // prints 2
echo $array{1}; // also prints 2
 
$string = "foo";
echo $string[0]; // prints "f"
echo $string{0}; // also prints "f"

Using the curly brace syntax will now trigger a deprecated notice in PHP 7.4 with the plan to remove the feature entirely in PHP 8.0 (or another future release).

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix these issues in #47751.

Specific Parameter Order Requirements For implode()

The implode() function accepts two parameters, $glue and $pieces. For historical reasons, implode() has accepted these parameters in any order, though it has been a recommendation that the documented order of implode( $glue, $pieces ) be used.

Starting in PHP 7.4, tolerance for passing the parameters in reverse order is deprecated and will be completely removed in PHP 8.0. Calling implode( $pieces, $glue ) in PHP 7.4 will trigger a deprecated notice.

Note: This also affects the join() function, which is an alias of implode() and accepts the same two parameters.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix these issues in #47746.

Accessing Array Offset on Non-Arrays/Objects

PHP has previously thrown a warning only when attempting to use an offset that is of an invalid type. However, starting with PHP 7.4, a warning will also be thrown when a container is of an invalid type.

While code which relies on the undocumented behavior of PHP returning null when attempting to array access a null/bool/int/float/resource will continue to work as expected, each and every instance of this will now throw a PHP E_WARNING.

This issue is most common when using array access on the outcome of functions with mixed return values, i.e. array|false. When the return values of these function are used, more type checking needs to be done before attempting to access the return value as if it were an array to prevent this warning.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix these issues in #47704.

Note: because this issue cannot be easily/reliably detected using static analysis tools, it is possible that there are more occurrences of this issue in Core. Please open a new ticket on Trac and tag it with the php74 keyword if additional issues of this type are discovered.

Concatenation & Plus/Minus Operator Precedence

In past versions of PHP, the operator precedence of the ., +, and - operators has been exactly the same. Because of this, operations are evaluated from left to right. However, because concatenated strings generally are not numbers, this often produces undesired behavior. It’s rare that the intended behavior is to add or subtract concatenated strings.

// Example:
echo "sum: " . $a + $b;
 
// Current behavior: evaluated left-to-right
echo ("sum: " . $a) + $b;
 
// Desired behavior: addition and subtraction have a higher precedence
echo "sum :" . ($a + $b);

In PHP 8.0, the . operator will have a lower precedence than + and -. This will ensure that additions and subtractions are always performed before concatenation occurs.

As an example, the expression '3' . '5' + 7 will now be equal to “312” instead of previously “42”.

Starting in PHP 7.4, a deprecation notice will be triggered for any unparenthesized expressions containing a . before a + or -. While this is a subtle change, every occurrence of this pattern will result in a change of behavior in PHP 8.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix this issue in #47441.

Deprecated: Magic Quotes Related Functions

The magic_quotes configuration was removed from PHP in version 5.4. The function implementations that check whether or not these settings have been enabled have returned false since then. Later, PHP 7.0 removed magic_quotes entirely.

As of PHP 7.4, get_magic_quotes_gpc() and get_magic_quotes_runtime() are now marked as deprecated and they are slated for removal in PHP 8.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix this issue in #47783.

Left-Associative Ternary Operators

In most other languages, the ternary operator is right-associative. However, in PHP, it is left-associative. This behavior is generally not useful and can be confusing for programmers who switch between different languages.

In PHP 7.4, nested ternaries without explicit parentheses will throw a deprecation warning In PHP 8.0, it will become a compile-time error instead.

<?php
1 ? 2 : 3 ? 4 : 5;   // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok

There were no occurrences of this pattern in WordPress Core, but it’s important to check your plugins, themes, and custom code to ensure PHP 7.4 compatibility. For more information about this change, see the accepted proposal on the official PHP RFC Wiki.

Compatibility Tooling

To help detect potential compatibility issues with supported versions of PHP, the PHPCompatibility checker has been added to WordPress Core with a custom tailored ruleset that extends the PHPCompatibilityWP ruleset.

If you build or maintain plugins or themes, it is highly recommended that you add the PHPCompatibility checker to your toolkit to make detecting PHP version compatibility issues easier and consistent. Aside from the array offset issue, all other issues mentioned in this article can be automatically detected through the use of PHPCompatibility.

When working on WordPress Core, composer compat can be run to scan the Core code base for potential compatibility issues. Furthermore, every TravisCI build will now contain a “PHP Compatibility Check” job that will scan for potential compatibility issues. This job is currently allowed to fail while the results are analyzed and the ruleset is refined to eliminate false positives.

For more information, see #46152 on Trac.

External Libraries & Dependencies

WordPress Core contributors have collaborated with the maintainers of several external libraries and dependencies to ensure compatibility with PHP 7.4.

getID3

The getID3 library was updated from v1.9.14 to v1.9.18. This update removes some occurrences of the now deprecated curly brace syntax and some code related to magic quotes. For more details, check out these pull requests, #47783, or [46112].

PHPMailer

The PHPMailer library was updated from v5.2.22 to v5.2.27 in Core and patched to prevent deprecated notices related to magic quotes from being triggered. Magic quotes has been completely removed from PHPMailer 6.0 and higher. #41750 exists to upgrade PHPMailer to the latest and greatest early in the 5.4 release cycle. For more details, check out #40472 and #47783, or the relevant changesets ([46097] and [46378]).

Requests

The Requests library was updated to address occurrences of the now deprecated curly brace syntax and accessing array offsets on non-arrays. For more details on these updates, see PR-346 and PR-370 in the Requests repository, #47746, or the related changesets ([46258] and [46416]).

SimplePie

The SimplePie library was patched in Core to prevent deprecated notices related to passing parameters to implode() in the incorrect order from being triggered. This issue is fixed in the most recent release of version 1.5.3. Upgrading the entire library to the latest and greatest with increased test coverage is being explored and is expected early in the 5.4 release cycle (see #36669). For more details, check out #47746 or [46260].

Other Updates

A few other libraries that no longer have an externally maintained canonical source have also been updated.

Summary

As always, reading through the complete upgrade document is highly recommended.

Even as WordPress Core continues to expand its support for new versions of PHP, the current support for old versions will remain as is at PHP 5.6.20 and higher until usage numbers show that the impact on users will be minimal.

There is a separate initiative to decrease the usage numbers for older versions of PHP being guided by the Core PHP team through the servehappy initiative. If you wish to help with this effort, please join the #core-php room in the Making WordPress Core Slack instance.

WordPress continues to encourage all users to run the latest and greatest versions of PHP. This includes PHP 7.4 upon its official release.

A full list of tickets related to PHP 7.4 support can be found on Trac.

Props @jrf and @jorbin for peer reviewing.

#5-3, #dev-notes, #php-7-4