Multisite: Cache absolute dirsize
paths to avoid PHP 8 fatal.
r49212 greatly improved the performance of get_dirsize()
, but also changed the structure of the data stored in the dirsize_cache
transient. It stored relative paths instead of absolute ones, and also removed the unnecessary size
array.
That difference in data structures led to a fatal error in the following environment:
- PHP 8
- Multisite
- A custom
WP_CONTENT_DIR
which is not a child of WP's ABSPATH
folder (e.g., Bedrock)
- The
upload_space_check_disabled
option set to 0
After upgrading to WP 5.6, the dirsize_cache
transient still had data in the old format. When wp-admin.php/index.php
was visited, get_space_used()
received an array
instead of an int
, and tried to divide it by another int
. PHP 7 would silently cast the arguments to match data types, but PHP 8 throws a fatal error:
Uncaught TypeError: Unsupported operand types: array / int
recurse_dirsize()
was using ABSPATH
to convert the absolute paths to relative ones, but some upload locations are not located under ABSPATH
. In those cases, $directory
and $cache_path
were identical, and that triggered the early return of the old array
, instead of the expected int
.
In order to avoid that, this commit restores the absolute paths, but without the size
array. It also adds a type check when returning cached values. Using absolute paths without size
has the result of overwriting the old data, so that it matches the new format. The type check and upgrade routine are additional safety measures.
Props peterwilsoncc, janthiel, helen, hellofromtonya, francina, pbiron.
Fixes #51913. See #19879.