Make WordPress Core

Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#53474 closed defect (bug) (fixed)

Improve Walker compatibility with PHP8

Reported by: sunxiyuan Owned by: SergeyBiryukov
Priority: normal Milestone: 5.8
Component: General Version: 5.8
Severity: major Keywords: has-patch php8
Cc: Focuses:

Description

PHP 8 introduced a new numeric and string comparison mechanism
For the following code:

<?php
0 == '';

True under PHP 7 and False under PHP 8.

There is the following statement in line 345 of the Walker class (wp-includes/class-wp-walker.php):

<?php
if ( 0 == $e->$parent_field ) {

If $e->$parent_field is an empty string, the judgment result of the statement in PHP 7 and PHP 8 will be inconsistent.

The question broke the reply order of my bbPress forum.

The offending code should be changed to:

<?php
if ( 0 == (int) $e->$parent_field ) {

Change History (7)

This ticket was mentioned in PR #1407 on WordPress/wordpress-develop by sunxiyuan.


5 years ago
#1

  • Keywords has-patch added

#2 @SergeyBiryukov
5 years ago

  • Keywords php8 added

#3 @SergeyBiryukov
5 years ago

  • Milestone Awaiting Review5.8
  • Owner set to SergeyBiryukov
  • Status newreviewing

#4 @SergeyBiryukov
5 years ago

Hi there, welcome to WordPress Trac! Thanks for the ticket and the patch.

I think we can use an empty() check here, for consistency with the change to the ::walk() method in [35876].

There are three similar instances of these checks in a few methods:

  • WP_Walker::walk()
  • WP_Walker::paged_walk()
  • WP_Walker::get_number_of_root_elements()

It looks like [35876] only fixed the first instance because the Menus screen only used the ::walk() method, and the other two methods can currently still throw a PHP notice if a non-existing property is checked. So using empty() in all the three places would fix that in the other two methods too, as well as the issue reported here.

I'll commit the change shortly, which also includes a unit test @aristath and I worked on.

#5 @SergeyBiryukov
5 years ago

  • Resolutionfixed
  • Status reviewingclosed

In 51204:

Code Modernization: Use a consistent check for parent items in WP_Walker.

This affects the ::walk(), ::paged_walk(), and ::get_number_of_root_elements() methods.

PHP 8 changes the way string to number comparisons are performed: https://wiki.php.net/rfc/string_to_number_comparison

In particular, checking if an empty string is equal to zero in PHP 8 evaluates to false, not true.

For the WP_Walker class, this resulted in an incorrect handling of parent items in a few methods.

By explicitly checking for an empty() value instead, we make sure the check works as expected in PHP 8 and earlier versions.

Follow-up to [35876], [48960], [49043], [49076].

Props sunxiyuan, aristath, SergeyBiryukov.
Fixes #53474.

#6 @sunxiyuan
5 years ago

empty() is indeed a better choice

Note: See TracTickets for help on using tickets.