Make WordPress Core

10/15/2021 10:52:43 PM (3 years ago)

FileSystem API: Fix autovivification deprecation notice in recurse_dirsize().

PHP natively allows for autovivification (auto-creation of arrays from falsey values). This feature is very useful and used in a lot of PHP projects, especially if the variable is undefined. However, there is a little oddity that allows creating an array from a false and null value.

The above quote is from the PHP 8.1 RFC and the (accepted) RFC changes the behaviour described above to deprecated auto creation of arrays from false. As it is deprecated, it _will_ still work for the time being, but as of PHP 9.0, this will become a Fatal Error, so we may as well fix it now.

The recurse_dirsize() function retrieves a transient and places it in the $directory_cache variable, but the get_transient() function in WP returns false when the transient doesn't exist, which subsequently can lead to the above mentioned deprecation notice.

By verifying that the $directory_cache variable is an array before assigning to it and initializing it to an empty array, if it's not, we prevent the deprecation notice, as well as harden the function against potentially corrupted transients where this transient would not return the expected array format, but some other variable type.

Includes adding dedicated unit tests for both the PHP 8.1 issue, as well as the hardening against corrupted transients.

Includes some girl-scouting: touching up a parameter description and some code layout.


Follow-up to [49212], [49744].

Props jrf, hellofromTonya.
See #53635.

1 edited


  • trunk/src/wp-includes/functions.php

    r51910 r51911  
    81218121 * @param string|array $exclude            Optional. Full path of a subdirectory to exclude from the total,
    81228122 *                                         or array of paths. Expected without trailing slash(es).
    8123  * @param int          $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global
    8124  *                                         and is measured from the moment WordPress started to load.
     8123 * @param int          $max_execution_time Optional. Maximum time to run before giving up. In seconds.
     8124 *                                         The timeout is global and is measured from the moment
     8125 *                                         WordPress started to load.
    81258126 * @param array        $directory_cache    Optional. Array of cached directory paths.
    81268127 *
    81958196                    }
    8197                     if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) {
     8198                    if ( $max_execution_time > 0 &&
     8199                        ( microtime( true ) - WP_START_TIMESTAMP ) > $max_execution_time
     8200                    ) {
    81988201                        // Time exceeded. Give up instead of risking a fatal timeout.
    81998202                        $size = null;
    82048207            closedir( $handle );
    82058208        }
     8209    }
     8211    if ( ! is_array( $directory_cache ) ) {
     8212        $directory_cache = array();
    82068213    }
Note: See TracChangeset for help on using the changeset viewer.