Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP 7.2: Warning: count(): Parameter must be an array or an object that implements Countable in... #8420

Closed
htdat opened this issue Dec 26, 2017 · 49 comments
Assignees
Labels
General [Pri] Normal [Type] Bug When a feature is broken and / or not performing as intended
Milestone

Comments

@htdat
Copy link
Member

htdat commented Dec 26, 2017

I myself can not replicate this issue.
The error and steps are based on what I collect from various sources:

Steps to reproduce the issue

  1. Activate Jetpack on PHP 7.x.
  2. Check log there is an error.
'Warning: count():
Parameter must be an array or an object that implements Countable in
wp-includes/post-template.php on line 284'.
  1. Using PHP 5.6.x, no issue.

What I expected

No warning at all in both PHP 5.6.x and PHP 7.x.

What happened instead

The error above with PHP 7.x.

More info

@htdat htdat added [Pri] Normal [Type] Bug When a feature is broken and / or not performing as intended labels Dec 26, 2017
@kraftbj
Copy link
Contributor

kraftbj commented Dec 26, 2017

I couldn't duplicate this either with the info provided.

The warning comes from https://github.com/WordPress/WordPress/blob/4.9.1/wp-includes/post-template.php#L284 which uses the global $pages so the test case may include a post using <!--nextpage--> tags (haven't tried that).

[Edit: Specifically looked at 7.0, not 7.1/7.2]

@oskosk
Copy link
Contributor

oskosk commented Dec 26, 2017

I could witness this message in my debug.log a couple of times while on PHP 7.2 (not on PHP 7.1 nor PHP 7.0) and looks like coming from core, not from Jetpack.

@oskosk
Copy link
Contributor

oskosk commented Dec 26, 2017

fwiw we have an ongoing master-issue tackling several reports of nuances with PHP 7.2 and Jetpack's code:

#8156

Also, we have a PR for introducing PHP 7.2 runs for unit tests in Travis... This PR has a few commits addressing some pieces of code in Jetpack that would error on PHP 7.2:

#8212

The problem is that the errors coming from core remain to be thrown in that branch when run on Travis, so we won't able to have PHP 7.2 passing unit tests until core fixes them.

@dsifford
Copy link

Not sure if this is helpful, but I also ran into this.

Here's the call stack:

get_header()
wp-content/themes/aliemu/page-home.php:4
locate_template()
wp-includes/general-template.php:41
load_template('~/wp-content/themes/aliemu/header.php')
wp-includes/template.php:647
wp_head()
wp-content/themes/aliemu/header.php:29
do_action('wp_head')
wp-includes/general-template.php:2614
jetpack_og_tags()
wp-includes/class-wp-hook.php:286
apply_filters('jetpack_open_graph_tags')
wp-content/plugins/jetpack/functions.opengraph.php:216
Jetpack_Twitter_Cards::twitter_cards_tags()
wp-includes/class-wp-hook.php:288
Jetpack_Media_Summary::get()
wp-content/plugins/jetpack/class.jetpack-twitter-cards.php:80
Jetpack_Media_Summary::get_excerpt()
wp-content/plugins/jetpack/_inc/lib/class.media-summary.php:57
apply_filters('get_the_excerpt')
wp-content/plugins/jetpack/_inc/lib/class.media-summary.php:314
wp_trim_excerpt()
wp-includes/class-wp-hook.php:286
get_the_content()
wp-includes/formatting.php:3308

@jeherve jeherve mentioned this issue Dec 29, 2017
13 tasks
@bobbingwide
Copy link
Contributor

Below is the call stack when I get the problem.
The message is produced when viewing an Attachment that has no caption, i.e. no excerpt.
$page is 0 and $pages is null.

I'm using the Twenty Seventeen theme with Jetpack 5.7

  1. bw_lazy_backtrace \wp-content\plugins\oik-bwtrace\libs\bwtrace.php:108 0
  2. bw_backtrace \wp-content\plugins\oik-bwtrace\includes\bwtrace-actions.php:276 0
  3. bw_trace_error_handler(2,count(): Parameter must be an array or an object that implements Countable,\wp-includes\post-template.php,284,array) \wp-includes\post-template.php:284 5
  4. get_the_content() \wp-includes\formatting.php:3308 1
  5. wp_trim_excerpt() \wp-includes\class-wp-hook.php:286 1
  6. apply_filters(,array) \wp-includes\plugin.php:203 2
  7. apply_filters(get_the_excerpt,) \wp-content\plugins\jetpack_inc\lib\class.media-summary.php:314 2
  8. get_excerpt(,,16,256) \wp-content\plugins\jetpack_inc\lib\class.media-summary.php:57 4
  9. get(810) \wp-content\plugins\jetpack\class.jetpack-twitter-cards.php:80 1
  10. twitter_cards_tags(array) \wp-includes\class-wp-hook.php:288 1
  11. apply_filters(array,array) \wp-includes\plugin.php:203 2
  12. apply_filters(jetpack_open_graph_tags,array,array) \wp-content\plugins\jetpack\functions.opengraph.php:216 3
  13. jetpack_og_tags() \wp-includes\class-wp-hook.php:286 1
  14. apply_filters(unsupported,array) \wp-includes\class-wp-hook.php:310 2
  15. do_action(array) \wp-includes\plugin.php:453 1
  16. do_action(wp_head) \wp-includes\general-template.php:2614 1
  17. wp_head \wp-content\themes\twentyseventeen\header.php:22 0
  18. require_once(\wp-content\themes\twentyseventeen\header.php) \wp-includes\template.php:688 1
  19. load_template(/wp-content/themes/twentyseventeen/header.php,1) \wp-includes\template.php:647 2
  20. locate_template(array,1) \wp-includes\general-template.php:41 2
  21. get_header \wp-content\themes\twentyseventeen\single.php:13 0
  22. include(\wp-content\themes\twentyseventeen\single.php) \wp-includes\template-loader.php:74 1
  23. require_once(\wp-includes\template-loader.php) \wp-blog-header.php:19 1
  24. require(\wp-blog-header.php) \index.php:17 1

The following change to the core function get_the_content() eliminates the problem

	if ( is_array( $pages ) ) {
		if ( $page > count( $pages ) ) // if the requested page doesn't exist
			$page = count( $pages ); // give them the highest numbered page that DOES exist
	} else { 	
		$page = 0;
	}

@oskosk oskosk changed the title PHP 7.x: Warning: count(): Parameter must be an array or an object that implements Countable in... PHP 7.2: Warning: count(): Parameter must be an array or an object that implements Countable in... Jan 6, 2018
@dd32
Copy link
Member

dd32 commented Jan 12, 2018

For an explanation of why Jetpack is triggering this, see https://core.trac.wordpress.org/ticket/42814#comment:17

tl;dr: Jetpack is calling a filter outside of the loop which expects to be run within the loop. It's not a bad expectation that it'd work (especially as it's only hit when there's an empty excerpt) but fixing the warnings don't make the underlying function work as expected

@kraftbj
Copy link
Contributor

kraftbj commented Jan 12, 2018

I think #8510 will be more explicit for our part, but there may still be a problem here.

get_the_excerpt( $post ) will still call the get_the_excerpt hook, passing along $post as a second argument, which is grand, but the default filters in WP do not pass the new argument along ( https://github.com/WordPress/WordPress/blob/6da54f0d9be5e2cf8659427a39f1f23b0465ce72/wp-includes/default-filters.php#L158 ), so we could be doing this right and still have a problem if I'm reading the code correctly. Relaying the potential core bug over to the trac ticket.

@kraftbj
Copy link
Contributor

kraftbj commented Jan 12, 2018

The above PR should resolve it if https://core.trac.wordpress.org/ticket/42814#comment:18 also lands.

@Flodu31
Copy link

Flodu31 commented Jan 17, 2018

Same problem here.
@kraftbj I don't understand your answer. Which file we need to modify to hide this error?
Thanks.
Florent

@bobbingwide
Copy link
Contributor

@Flodu31 For my example, the workaround is to create a Caption ( Excerpt ) for the Attachment.

@Flodu31
Copy link

Flodu31 commented Jan 17, 2018

Ok thanks, but for me I think it's not the problem because on pages that has no attachment, the problem is present too...

@kraftbj
Copy link
Contributor

kraftbj commented Jan 20, 2018

@Flodu31 If you could include a call stack and more information about where you're seeing it, that would be helpful. Is it on a normal post/page or a CPT? Is there an excerpt for that post/page/CPT already?

@bobbingwide
Copy link
Contributor

bobbingwide commented Jan 20, 2018

@kraftbj Here's the call stack for a post with no content at all and no excerpt either.
The problem doesn't happen if the post has an excerpt.

In order to get the problem for the page post type it has to have 'excerpt' post type support and have no content, nor an attached image.

Jetpack 5.7, Twenty Seventeen 1.4, WordPress 4.9.2

  1. bw_lazy_backtrace \wp-content\plugins\oik-bwtrace\libs\bwtrace.php:108 0
  2. bw_backtrace \wp-content\plugins\oik-bwtrace\includes\bwtrace-actions.php:276 0
  3. bw_trace_error_handler(2,count(): Parameter must be an array or an object that implements Countable,\wp-pompey\wp-includes\post-template.php,284,array) \wp-pompey\wp-includes\post-template.php:284 5
  4. get_the_content() wp-pompey\wp-includes\formatting.php:3308 1
  5. wp_trim_excerpt() wp-pompey\wp-includes\class-wp-hook.php:286 1
  6. apply_filters(,array) wp-pompey\wp-includes\plugin.php:203 2
  7. apply_filters(get_the_excerpt,) wp-pompey\wp-content\plugins\jetpack_inc\lib\class.media-summary.php:314 2
  8. get_excerpt(,,16,256) jetpack_inc\lib\class.media-summary.php:57 4
  9. get(965) jetpack\class.jetpack-twitter-cards.php:80 1
  10. twitter_cards_tags(array) wp-includes\class-wp-hook.php:288 1
  11. apply_filters(array,array) wp-includes\plugin.php:203 2
  12. apply_filters(jetpack_open_graph_tags,array,array) jetpack\functions.opengraph.php:216 3
  13. jetpack_og_tags() wp-includes\class-wp-hook.php:286 1
  14. apply_filters(unsupported,array) wp-includes\class-wp-hook.php:310 2
  15. do_action(array) C:\apache\htdocs\wp-pompey\wp-includes\plugin.php:453 1
  16. do_action(wp_head) C:\apache\htdocs\wp-pompey\wp-includes\general-template.php:2614 1
  17. wp_head C:\apache\htdocs\wp-pompey\wp-content\themes\twentyseventeen\header.php:22 0
  18. require_once(C:\apache\htdocs\wp-pompey\wp-content\themes\twentyseventeen\header.php) C:\apache\htdocs\wp-pompey\wp-includes\template.php:688 1
  19. load_template(C:\apache\htdocs\wp-pompey/wp-content/themes/twentyseventeen/header.php,1) C:\apache\htdocs\wp-pompey\wp-includes\template.php:647 2
  20. locate_template(array,1) C:\apache\htdocs\wp-pompey\wp-includes\general-template.php:41 2
  21. get_header C:\apache\htdocs\wp-pompey\wp-content\themes\twentyseventeen\single.php:13 0
  22. include(C:\apache\htdocs\wp-pompey\wp-content\themes\twentyseventeen\single.php) C:\apache\htdocs\wp-pompey\wp-includes\template-loader.php:74 1
  23. require_once(C:\apache\htdocs\wp-pompey\wp-includes\template-loader.php) C:\apache\htdocs\wp-pompey\wp-blog-header.php:19 1
  24. require(C:\apache\htdocs\wp-pompey\wp-blog-header.php) C:\apache\htdocs\wp-pompey\index.php:17 1

Basically the same as before but I got bored stripping out unnecessary bits of the file names.

@dsifford
Copy link

dsifford commented Feb 4, 2018

FWIW,

Changing this code from this....

if ( empty( $post->post_password ) ) {
    $return['excerpt']       = self::get_excerpt( $post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars'] );
    $return['count']['word'] = self::get_word_count( $post->post_content );
    $return['count']['word_remaining'] = self::get_word_remaining_count( $post->post_content, $return['excerpt'] );
    $return['count']['link'] = self::get_link_count( $post->post_content );
}

to this...

if ( empty( $post->post_password ) && has_excerpt() ) {
    $return['excerpt']       = self::get_excerpt( $post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars'] );
    $return['count']['word'] = self::get_word_count( $post->post_content );
    $return['count']['word_remaining'] = self::get_word_remaining_count( $post->post_content, $return['excerpt'] );
    $return['count']['link'] = self::get_link_count( $post->post_content );
}

Completely resolves the issue for me.

@pmciano
Copy link

pmciano commented Feb 4, 2018

Getting a report of this in the forums:

Warning: count(): Parameter must be an array or an object that implements Countable in /home/tazejesa/public_html/wp-includes/media.php on line 1206

Requesting additional information.

Update:

I see it on the backend and on the first product of every category and on every product page.

Error

https://tazee.co/product-category/apparel/

@dsifford
Copy link

dsifford commented Feb 5, 2018

@pmciano Does my solution that I posted work? Is there something I am overlooking?

@zinigor
Copy link
Member

zinigor commented Feb 5, 2018

@dsifford thanks for the patch! Unfortunately, I don't think it's going to work, because the code runs inside the wp_head hook, which does not yet have a global post set. has_excerpt will always be false here.

There's a candidate PR that we're currently looking at (#8510), but it has the same drawback as your solution: we're ignoring posts that do not have an excerpt. If you have an idea how we can both fix the warning and not exclude a subset of posts, please let us know!

@dsifford
Copy link

dsifford commented Feb 5, 2018

@zinigor I guess I'm still confused as to how get_excerpt is acceptible, but has_excerpt is not?

What about just passing $post->ID to the has_excerpt call?

edit: Oops, just noticing that the get_excerpt call is not the built-in one from WordPress. Disregard.

@zinigor
Copy link
Member

zinigor commented Feb 6, 2018

@dsifford yes, passing an ID to has_excerpt would work, but again, that would change the current behaviour by excluding posts that do not have an excerpt set.

@ghost
Copy link

ghost commented Feb 7, 2018

Any update on this issue @zinigor?

@zinigor
Copy link
Member

zinigor commented Feb 7, 2018

@ollietigs sorry, nothing new at this time. Please follow #8510 for updates, this is where the problem will be fixed.

@Moataz01210049831
Copy link

put the_content in if condition solve the problem for me

@StefMattana
Copy link

@joendotcom
Copy link

joendotcom commented Apr 8, 2018

I can confirm that @LaQuay's workaround works.

Toggling off WP Admin → Jetpack → Settings → Sharing → Sharing buttons → Add sharing buttons to your posts fixed the issue. (Likes made no difference in this case.)

I have a live site with the issue here: https://joen.com/contact/

Error:
Warning: count(): Parameter must be an array or an object that implements Countable in [...] /wp-includes/post-template.php on line 284

Here is the line 284-285 of /wp-includes/post-template.php:

if ( $page > count( $pages ) ) // if the requested page doesn't exist
	$page = count( $pages ); // give them the highest numbered page that DOES exist

Screencast:

screen capture on 2018-04-08 at 13-28-52

@pabloacastillo
Copy link

Installing YOAST SEO plugin somehow fixed this issue for me.

@zinigor
Copy link
Member

zinigor commented Jun 26, 2018

@pabloacastillo Jetpack checks for other plugins and disables some of its functionality in case it could conflict. That could be the case, or maybe you have updated to the newer version simultaneously with installing Yoast. Please let us know here or in support channels if you are still having any problems.

@rubensjunior-eti-br
Copy link

Thanks pabloacastillo when installing YOAST SEO the problem was solved!

@atanaspuskulev
Copy link

I have found this with ZF 1.12 running on PHP 7.2 (count files validator).
If correctly remember it was:

$this->_count = count($this->_files);

where $this->_files was NULL;

$this->_count = $this->_files !== null ? count($this->_files) : 0; -> did the trick.

@rustydigg918
Copy link

I've been shown a warning message at my add product page post upgrading PHP into 7.2 version, it says "Warning:** count(): Parameter must be an array or an object that implements Countable in C:\xampp\htdocs\E-comm\register_page\add_product.php on line 281
"

@paulschreiber
Copy link
Contributor

@rustydigg918 That looks like a bug in your own code, not Jetpack.

@juanmiguel3008
Copy link

He tenido el mismo problema:
He modificado en el Helper.php
Esto: return (count($permission) > 0); Por Esto: return (count([$permission]) > 0);
solo he aumentado los corchetes []

@etwordpress01
Copy link

Hi Guys

This could be due to null values given to WordPress functions. Like If you give null value to wp_trim_excerpt

wp_trim_excerpt( $post->post_content ); where $post->post_content = null

https://github.com/ThemeFuse/Unyson/issues/3526

Thanks

@zinigor
Copy link
Member

zinigor commented Jul 24, 2018

Thanks @etwordpress01 ! Exactly, if you're interested in more detail you can click around this PR to see more about the technical details of how it was fixed: #9348

@cpbotha
Copy link

cpbotha commented Sep 2, 2018

Just in case this helps anyone: The Jupiter Wordpress theme is suffering from the same issue. I fixed it with a one-line change in their code, see below.

get_the_excerpt() is invoked by jupiter in its mk_open_graph_meta() where it builds the FB opengraph variables. When no excerpt is specified for a post, it also ends up in get_the_content() with $pages == NULL. Oops.

To fix this for this one specific case, I changed their code in framework/helpers/wp_head.php as follows:

$output .= '<meta property="og:description" content="' . esc_attr( get_the_excerpt() ) . '"/>';

to

$output .= '<meta property="og:description" content="' . 
    esc_attr( has_excerpt($post->ID) ? get_the_excerpt() : wp_trim_excerpt($post->post_content) ) .
   '"/>';

@abdessamadely
Copy link

I had the issue like:
issue

i did add an extra condition to the line 284
from:
if ( $page > count( $pages ) ) // if the requested page doesn't exist $page = count( $pages ); // give them the highest numbered page that DOES exist

to:
if (!empty($post_excerpt)) if ( $page > count( $pages ) ) // if the requested page doesn't exist $page = count( $pages ); // give them the highest numbered page that DOES exist

@jeherve
Copy link
Member

jeherve commented Sep 6, 2018

@abdorabi I would strongly recommend against editing core WordPress files to solve this issue. Instead, it may be best to deactivate all your plugins, one at a time, until you find the plugin that is causing the issue. If that does not help, try switching to one of the default themes to make sure your theme is not the cause of the problem.

Once you find what is causing the problem, you can contact the plugin / theme author to ask them to take a look. You can point them to this issue if they need more info, or ask them to take a look at this PR if they want to know how this was fixed for the Jetpack plugin, as an example.

@abdessamadely
Copy link

Thank you @jeherve i will return the wordpress core as it was

@Irissu
Copy link

Irissu commented Dec 4, 2018

Just in case this helps anyone: The Jupiter Wordpress theme is suffering from the same issue. I fixed it with a one-line change in their code, see below.

get_the_excerpt() is invoked by jupiter in its mk_open_graph_meta() where it builds the FB opengraph variables. When no excerpt is specified for a post, it also ends up in get_the_content() with $pages == NULL. Oops.

To fix this for this one specific case, I changed their code as follows:

$output .= '<meta property="og:description" content="' . esc_attr( get_the_excerpt() ) . '"/>';

to

$output .= '<meta property="og:description" content="' . 
    esc_attr( has_excerpt($post->ID) ? get_the_excerpt() : wp_trim_excerpt($post->post_content) ) .
   '"/>';

cpbotha I'm struggled with the same code error with Jupiter Theme... but I can't found where is the file I have to edit.. Could you help me? :( Thanks!

@cpbotha
Copy link

cpbotha commented Dec 4, 2018

@Irissu I've amended my post above with the correct filename framework/helpers/wp_head.php.

@krazykirby8
Copy link

so if you've updated your php version above 7.1.9 the 7.2 count() no longer works as a null/empty check, cause the parameter either has to be validated as a collection or an array.

@jeherve
Copy link
Member

jeherve commented Dec 20, 2018

I will now be locking this conversation, as the issue mentioned here was fixed for the Jetpack plugin in #9348.

If you do run into the problem on your site, it is not caused by the Jetpack plugin and the patch I linked to above will not be useful to you; the problem is caused by a different plugin / theme / service on your site, and happens because your server uses PHP 7.2.

To find out what plugin or theme is causing the issue, try to deactivate all plugins, one at a time, until the problem disappears. If that does not help, try switching to a different theme for a few minutes.
Once you've managed to pinpoint the source of the problem, you can contact the theme / plugin author and ask them to review their use of the get_the_excerpt function. You can point them to this trac ticket if they need more information:
https://core.trac.wordpress.org/ticket/42814

@Automattic Automattic locked as resolved and limited conversation to collaborators Dec 20, 2018
@kraftbj
Copy link
Contributor

kraftbj commented Mar 20, 2019

Note that WordPress 5.2 will resolve the root issue that led to Jetpack throwing this warning ( https://core.trac.wordpress.org/changeset/44941 ). I'm reopening #8510 to look at better handling the excerpt now that Core more fully supports the expected result of using get_the_excerpt outside of the loop.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
General [Pri] Normal [Type] Bug When a feature is broken and / or not performing as intended
Projects
None yet
Development

Successfully merging a pull request may close this issue.