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 · 44 comments

Comments

Projects
None yet
@htdat
Contributor

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

@kraftbj

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

dsifford commented Dec 28, 2017

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 added the General label Dec 29, 2017

@jeherve jeherve referenced this issue Dec 29, 2017

Open

PHP 7.2 Compatibility #8156

10 of 10 tasks complete
@bobbingwide

This comment has been minimized.

Contributor

bobbingwide commented Jan 6, 2018

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 from PHP 7.x: Warning: count(): Parameter must be an array or an object that implements Countable in... to PHP 7.2: Warning: count(): Parameter must be an array or an object that implements Countable in... Jan 6, 2018

@dd32

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Contributor

bobbingwide commented Jan 17, 2018

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

@Flodu31

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

dsifford commented Feb 5, 2018

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

@zinigor

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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.

@ollietigs

This comment has been minimized.

ollietigs commented Feb 7, 2018

Any update on this issue @zinigor?

@zinigor

This comment has been minimized.

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

This comment has been minimized.

Moataz01210049831 commented Feb 17, 2018

put the_content in if condition solve the problem for me

@victorwitkamp

This comment has been minimized.

victorwitkamp commented Mar 19, 2018

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

@KokkieH

This comment has been minimized.

@jeiseman

This comment has been minimized.

Contributor

jeiseman commented Mar 27, 2018

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

@danjjohnson

This comment has been minimized.

danjjohnson commented Mar 28, 2018

Also reported in 1011965-zen

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

@drazisil

This comment has been minimized.

drazisil commented Mar 28, 2018

Confirmed that the message is gone in version 5.9.

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

@bhansley

This comment has been minimized.

bhansley commented Mar 31, 2018

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

@drazisil

This comment has been minimized.

drazisil commented Mar 31, 2018

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

@StefMattana

This comment has been minimized.

@joendotcom

This comment has been minimized.

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

This comment has been minimized.

pabloacastillo commented Jun 25, 2018

Installing YOAST SEO plugin somehow fixed this issue for me.

@zinigor

This comment has been minimized.

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

This comment has been minimized.

rubensjunior-eti-br commented Jun 26, 2018

Thanks pabloacastillo when installing YOAST SEO the problem was solved!

@atanaspuskulev

This comment has been minimized.

atanaspuskulev commented Jul 3, 2018

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

This comment has been minimized.

rustydigg918 commented Jul 17, 2018

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

This comment has been minimized.

Contributor

paulschreiber commented Jul 18, 2018

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

@etwordpress01

This comment has been minimized.

etwordpress01 commented Jul 24, 2018

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Abdorabi commented Sep 6, 2018

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

This comment has been minimized.

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.

@Abdorabi

This comment has been minimized.

Abdorabi commented Sep 6, 2018

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

bepixeld added a commit to bepixeld/Page-Builder-Framework that referenced this issue Oct 29, 2018

Warning with Elementor Page Builder
When editing a Template in Elementor with Page Builder Theme active, there is a PHP Warning: count(): Parameter must be an array or an object that implements Countable in wp-includes/post-template.php on line 284.
Because the global variables $page, $pages are not initialized. If function the_post() is called before, then everything is OK.
My Environment: Apache, PHP 7.2, Wordpress 4.9.8, Elementor 2.2.7, Page Builder Framework 1.11.1
I thing its similar problem with jetpack and PHP7.2: Automattic/jetpack#8420
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment