#43374 closed defect (bug) (fixed)
PHP 7.2 Warning: count(): Parameter must be an array or an object that implements Countable in /wp-includes/theme.php on line 356
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 4.9.6 | Priority: | normal |
| Severity: | minor | Version: | |
| Component: | Themes | Keywords: | good-first-bug has-patch |
| Focuses: | Cc: |
Description
After upgrading to PHP 7.2 from 7.0 we observed PHP warnings on every pageload. It looks like get_theme_roots() runs count() on global $wp_theme_directories without checking the value first.
Proposed solution: check if empty($wp_theme_directories) before performing count().
patched version of get_theme_roots (wp-includes/theme.php line 356 in WP 4.9.4)
function get_theme_roots() {
global $wp_theme_directories;
if ( empty($wp_theme_directories) || count($wp_theme_directories) <= 1 )
return '/themes';
$theme_roots = get_site_transient( 'theme_roots' );
if ( false === $theme_roots ) {
search_theme_directories( true ); // Regenerate the transient.
$theme_roots = get_site_transient( 'theme_roots' );
}
return $theme_roots;
}
We haven't observed this in a clean WordPress install, so we aren't sure why $wp_theme_directories would be empty, but this patch resolves the PHP warning while maintaining the existing, expected PHP <7.2 behavior.
Attachments (3)
Change History (14)
#1
@
8 years ago
- Focuses coding-standards removed
- Resolution set to duplicate
- Status changed from new to closed
#2
@
8 years ago
- Severity changed from normal to minor
Hi @jrf,
Thank you for your insight on the proposed solution.
If $wp_theme_directories should always be an array, then this conditional addresses the issue more comprehensively:
if ( empty($wp_theme_directories) || ( is_array($wp_theme_directories) && count($wp_theme_directories) <= 1 ) ) {
This way, we still return the default '/themes' if $wp_theme_directories is null, zero, or other invalid empty() value, OR is a valid array with 1 or fewer items. count() is only executed if is_array() passes.
I looked into #42814 before submitting this, but believe this to be a distinct issue because that ticket does not cover this specific use of count() in get_theme_roots(). The warning is effectively the same but in this case it is being generated in wp-includes/theme.php which is not referenced at all in #42814.
I may be missing something but I do not believe #42814 addresses this.
#3
@
8 years ago
If $wp_theme_directories should always be an array, then this conditional addresses the issue more comprehensively:
if ( empty($wp_theme_directories) || ( is_array($wp_theme_directories) && count($wp_theme_directories) <= 1 ) ) {
Yes, however, now you're using a superfluous condition as the empty() is not needed is you first do an is_array(). Rewriting to the below would be simpler: (presuming $wp_theme_directories is always defined, otherwise an isset() would still be needed)
if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) ) {
I may be missing something but I do not believe #42814 addresses this.
AFAIK ticket #42814 is intended as the master ticket for these type of warnings, so I would suggest continuing the discussion there.
#4
@
8 years ago
- Keywords needs-patch good-first-bug added
- Milestone changed from Awaiting Review to Future Release
- Resolution duplicate deleted
- Status changed from closed to reopened
- Version 4.9.4 deleted
A check for is_array() makes sense here. This would be consistent with wp_get_themes() for example.
#42814 is not a master ticket.
#7
@
8 years ago
#43583 will introduce an is_countable() polyfill for the PHP 7.3 function with the same name. I think it makes sense to start using that function here to fix this warning.
43374.patch utilizes the is_countable() function to avoid the PHP warning. Of course, this depends on the patch in #43583 being committed first.
Hi there and thanks for your report!
Please note that this is already being tracked in #42814.
As a side-note, your proposed solution is definitely not the correct way to go about it as
empty()will also returnfalseon a non-empty string, a non-0 integer etc. and all of those would still cause the same warning to be thrown in PHP 7.2.