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

Created on 26 Dec 2017  Â·  50Comments  Â·  Source: Automattic/jetpack

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

General [Pri] Normal [Type] Bug

Most helpful comment

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.

All 50 comments

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]

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.

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

https://github.com/Automattic/jetpack/issues/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:

https://github.com/Automattic/jetpack/pull/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.

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

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;
    }

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

I think https://github.com/Automattic/jetpack/pull/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.

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

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

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

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

@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?

@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.

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.

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/

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

@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!

@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.

@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.

Any update on this issue @zinigor?

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

        if(have_posts()){


                the_post();
            }

            the_content();

?>
put the_content in if condition solve the problem for me

In my case, deactivating the "Sharing > Sharing Buttons" in Jetpack solved this problem. Which is a valid "workaround" for me.

Same for me. The error is gone after deactivating the sharing buttons

I was able to fix the problem by modifying the function Jetpack_Media_Summary::get_excerpt by adding a check for $post_excerpt not being empty before applying the filter (line 314 of jetpack/_inc/lib/class.media_summary.php):

                        if (!empty($post_excerpt))
                            $post_excerpt = apply_filters( 'get_the_excerpt', $post_excerpt );

Also reported in 1011965-zen

User fixed it using https://core.trac.wordpress.org/attachment/ticket/42814/42814.patch

Confirmed that the message is gone in version 5.9.

edit: I lied, it apparently just took a little while to come back :(

As a followup to @LaQuay 's workaround, I had to turn off both:

"Sharing > Sharing Buttons"
"Sharing > Publicize connections"

to quiet the error messages. Neither one alone was enough to stop them, and neither one of those is a feature that I care about at all.

JetPack 5.9
Wordpress 4.9.4
PHP 7.2.3

That's not a workaround for me, because Sharing Buttons is the only reason I'm using JetPack.

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

Installing YOAST SEO plugin somehow fixed this issue for me.

@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.

Thanks pabloacastillo when installing YOAST SEO the problem was solved!

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.

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
"

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

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 []

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

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: https://github.com/Automattic/jetpack/pull/9348

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) ) .
   '"/>';

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

@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.

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

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!

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

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.

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

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.

Was this page helpful?
0 / 5 - 0 ratings