Make WordPress Core

Opened 6 years ago

Closed 5 years ago

Last modified 3 years ago

#42814 closed defect (bug) (fixed)

PHP 7.2 Warning: ...wp-includes/post-template.php on line 284

Reported by: internetwerk's profile internetwerk Owned by: boonebgorges's profile boonebgorges
Milestone: 5.2 Priority: normal
Severity: normal Version: 4.5
Component: Posts, Post Types Keywords: dev-feedback has-patch 2nd-opinion php73 has-unit-tests
Focuses: Cc:

Description

Warning with PHP 7.2:

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

---> https://www.blogseye.com/convert-a-web-page-to-a-wordpress-theme-in-5-minutes/
---> https://neu.internetwerk.de/business-webhosting/bestellformular/

Attachments (11)

42814.patch (1.5 KB) - added by Shital Patel 6 years ago.
if it is array then use count function, otherwise set default variable value zero
warning_count.png (135.8 KB) - added by Shital Patel 6 years ago.
42814.diff (1.6 KB) - added by kraftbj 6 years ago.
Updating wp_trim_excerpt to accept a post object
42814.2.diff (1.6 KB) - added by spacedmonkey 5 years ago.
42814.3.diff (7.5 KB) - added by spacedmonkey 5 years ago.
42814.4.diff (8.5 KB) - added by spacedmonkey 5 years ago.
42814.5.diff (12.0 KB) - added by spacedmonkey 5 years ago.
42814.7.diff (12.2 KB) - added by spacedmonkey 5 years ago.
42814.8.diff (15.9 KB) - added by spacedmonkey 5 years ago.
42814.6.diff (10.3 KB) - added by boonebgorges 5 years ago.
42814.9.diff (16.3 KB) - added by boonebgorges 5 years ago.

Download all attachments as: .zip

Change History (126)

@Shital Patel
6 years ago

if it is array then use count function, otherwise set default variable value zero

#1 follow-up: @Shital Patel
6 years ago

  • Keywords has-patch added

#2 @dd32
6 years ago

Hey @internetwerk and welcome to Trac!

Do you know what circumstances can be used to trigger these warnings? Are they duplicatable on a clean WordPress install?

Looking at 42814.patch these seem to be things which should always be arrays, knowing when it's not an array would be beneficial to fixing this.

#3 in reply to: ↑ 1 @internetwerk
6 years ago

  • Resolution set to worksforme
  • Status changed from new to closed

Thank You @Shital Patel and @dd32, it works fine!

---> https://www.internetwerk.de/webspace-domain-bestellformular/
---> No errors, no warnings with PHP 7.2. after patch post-template.php

(Sorry for my bad English!)

#4 @dd32
6 years ago

  • Keywords needs-testing reporter-feedback added; has-patch removed
  • Resolution worksforme deleted
  • Status changed from closed to reopened

We only close tickets when the patch is committed to core.

I'm not happy with committing 42814.patch blindly, unless someone can show how to duplicate it. It seems to be patching over a larger underlying problem.

If someone can post a scenario where $pages / $content / $custom[$key] is not an array, that'd be appreciated.

#5 follow-up: @Shital Patel
6 years ago

Hello @dd32 ,

The problem is that $pages,$content,$custom[$key] could be null in some cases, and PHP 7.2 doesn't allow count(null);

So, We can set zero value.

#6 in reply to: ↑ 5 ; follow-up: @dd32
6 years ago

Replying to Shital Patel:

Hello @dd32 ,

The problem is that $pages,$content,$custom[$key] could be null in some cases, and PHP 7.2 doesn't allow count(null);

So, We can set zero value.

Yes, But I want to know *why* they're a null value, as they should always be an array unless I've missed something. That's why I want to know the steps to reproduce it.

#7 in reply to: ↑ 6 @rodrigogomes
6 years ago

Replying to dd32:

Replying to Shital Patel:

Hello @dd32 ,

The problem is that $pages,$content,$custom[$key] could be null in some cases, and PHP 7.2 doesn't allow count(null);

So, We can set zero value.

Yes, But I want to know *why* they're a null value, as they should always be an array unless I've missed something. That's why I want to know the steps to reproduce it.

@dd32 I'm getting the same error, in different WordPress installs.

I could not identify what caused it. But apparently it began to appear after I imported the demo of a premium theme.

Last edited 6 years ago by rodrigogomes (previous) (diff)

#8 @azrobbo
6 years ago

I ran into this issue while performing upgrade/failover tests against multiple WP sites at the same time - but encountered this error on only one site.

The "problem site" is very simple and is using a 3-year old premium theme by StudioPress called Executive Pro which uses Genesis (also by StudioPress) as its parent theme.

  • Because the same actions were performed against multiple sites, and only one exhibited this error, it appears to be caused by something site specific (not mere actions alone).

While, I cannot explain how to reproduce the error, I can provide this list of actions I performed that caused the error (on one site, but not others).

Note: I'm using a containerized WP implementation - each site has it's own WP container with "/var/www/html" mapped to site specific persistent storage, and share a common MySQL with seperate DB's for each site & persistent storage.

The actions performed:

  • Manually logged into each site's wp-admin and upgraded it to the latest WP version
    • at this point all sites worked great
  • Pulled the latest WP image and relaunched all the sites using the new image. (This was done to test failing-over to a new host, where images would need to be pulled.)
    • I thought this redundant, as the "/var/www/html" dir, and MySQL already contained the files & data for the new WP version from the previous step.
    • However, immediately after relaunching with the new WP image, the error appeared on the "problematic site" - but not any others.

Attempts to fix:

  • i tried restoring the DB & user HTML files from backups: (1) before the upgrade and (2) after the manual-upgrade but before pulling the image - neither stopped the error message
  • I temporarily stopped the error by commenting out lines 284-285 as they don't appear to apply to the "problematic site". (I did not need to change, or comment out, and other lines)

I can share additional information/data from the site in question if necessary (please contact me offline as I can't post it publicly).

Last edited 6 years ago by azrobbo (previous) (diff)

#9 @jlapitan
6 years ago

This error appears when you have jetpack plugin enabled

#10 @Theolobias
6 years ago

Same error on my website using WordPress 4.9.1 and PHP 7.2.0 with Jetpack Plugin activated. Deactivating Jetpack results in the error disappearing. Seems to be no issue with PHP 7.0.26.

#11 follow-up: @kenwood31
6 years ago

Hey,

Yes, it happens when Jetpack plugin is activated.
After checking several settings on this plugin, I noticed this is due to the feature "publicize".

In my case, I didn't use it so I just switched it off (in Jetpack > Settings > Sharing) and the error is not displayed anymore.
Hope it will help you to fix it before a real fix on this ;)

#12 in reply to: ↑ 11 ; follow-up: @Theolobias
6 years ago

Replying to kenwood31:

Hey,

Yes, it happens when Jetpack plugin is activated.
After checking several settings on this plugin, I noticed this is due to the feature "publicize".

In my case, I didn't use it so I just switched it off (in Jetpack > Settings > Sharing) and the error is not displayed anymore.
Hope it will help you to fix it before a real fix on this ;)

I can't confirm this - deactivating the Pubilcize-feature doesn't change anything. (Maybe in your case it's due to another PHP-version?)

#13 in reply to: ↑ 12 @rodrigogomes
6 years ago

Replying to Theolobias:

Replying to kenwood31:

Hey,

Yes, it happens when Jetpack plugin is activated.
After checking several settings on this plugin, I noticed this is due to the feature "publicize".

In my case, I didn't use it so I just switched it off (in Jetpack > Settings > Sharing) and the error is not displayed anymore.
Hope it will help you to fix it before a real fix on this ;)

I can't confirm this - deactivating the Pubilcize-feature doesn't change anything. (Maybe in your case it's due to another PHP-version?)

Disabling Publicize connections and Sharing buttons actually removes the error.
The problem is actually in the Jetpack plugin.

#14 @bobbingwide
6 years ago

I've updated the Issue raised against Jetpack with my findings.
https://github.com/Automattic/jetpack/issues/8420

For me the problem occurs when viewing an Attachment that doesn't have a caption ( i.e. excerpt ).
Theme Twenry Seventeen, Jetpack 5.7

My change to get_the_content() was simpler.

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

I didn't try fixing Jetpack.

Don't ask me why the next line works, but it does!

$content = $pages[ $page - 1 ];

$content becomes null.

Last edited 6 years ago by bobbingwide (previous) (diff)

#15 @lofesa
6 years ago

I can confirm the issue but w/o Jetpack. Only php upgraded from 7.0 to 7.2

#16 follow-up: @Cibulka
6 years ago

In my case, it was a call to get_the_excerpt(), when the page had none. I have fixed it roughly this way:

global $post;
$excerpt = !empty($post->post_excerpt) ? get_the_excerpt() : null;

PHP 7.2 as well.

#17 @dd32
6 years ago

  • Keywords needs-patch added; needs-testing reporter-feedback removed

Duplicated it against an attachment when Jetpack is in use (and out of development mode)

Here's a backtrace:

( ! ) Warning: count(): Parameter must be an array or an object that implements Countable in ../wp-includes/post-template.php on line 292
Call Stack
#	Time	Memory	Function	Location
1	0.0002	394584		{main}( )	.../index.php:0
2	0.0004	396520		require( '.../wp-blog-header.php' )	.../index.php:17
3	0.8743	35298240	require_once( '.../wp-includes/template-loader.php' )	.../wp-blog-header.php:19
4	0.8863	35641272	include( '.../wp-content/themes/twentyseventeen/single.php' )	.../template-loader.php:77
5	0.8863	35641272	get_header( )	.../single.php:13
6	0.8863	35641648	locate_template( )	.../general-template.php:41
7	0.8864	35641744	load_template( )	.../template.php:653
8	0.8865	35648296	require_once( '.../wp-content/themes/twentyseventeen/header.php' )	.../template.php:695
9	0.8873	35656288	wp_head( )	.../header.php:22
10	0.8873	35656288	do_action( )	.../general-template.php:2661
11	0.8873	35656664	WP_Hook->do_action( )	.../plugin.php:465
12	0.8873	35656664	WP_Hook->apply_filters( )	.../class-wp-hook.php:310
13	0.9288	35757880	jetpack_og_tags( )	.../class-wp-hook.php:286
14	0.9308	35762904	apply_filters( )	.../functions.opengraph.php:216
15	0.9308	35763304	WP_Hook->apply_filters( )	.../plugin.php:208
16	0.9853	35835632	Jetpack_Twitter_Cards::twitter_cards_tags( )	.../class-wp-hook.php:288
17	0.9918	35822616	Jetpack_Media_Summary::get( )	.../class.jetpack-twitter-cards.php:80
18	0.9920	35823920	Jetpack_Media_Summary::get_excerpt( )	.../class.media-summary.php:57
19	0.9920	35823920	apply_filters( )	.../class.media-summary.php:314
20	0.9920	35824320	WP_Hook->apply_filters( )	.../plugin.php:208
21	0.9920	35825072	wp_trim_excerpt( )	.../class-wp-hook.php:286
22	0.9920	35825072	get_the_content( )	.../formatting.php:3568

The reason this is being run into, is because Jetpacks Jetpack_Media_Summary::get_excerpt calls apply_filters( 'get_the_excerpt', $post_excerpt ); where $post_excerpt is empty, and before WP_Query::setup_postdata()/the_post() is called. get_the_content() currently expects that it'll be used within an actual post content loop (which is a fairly sane assumption to make, except plugins do weird things)
Jetpack is doing it wrong here, but in a subtle way that would be expected to work by many.

Now, we can paper over this by checking if it's an array, but that's not the actual problem at play here.
The issue is that get_the_content() relies upon WP_Query::setup_postdata() having being run in order to actually return the correct data, and in this case, it can't as the source variables for the content are not yet setup.
The more correct fix would be to ensure that get_the_content() can split content into pages for correct return values even when it's not within the loop.

#18 @kraftbj
6 years ago

  • Component changed from General to Formatting
  • Keywords has-patch added; needs-patch removed
  • Version changed from 4.9.1 to 4.5

I see where you're going with this @dd32, but I think there's another problem in play.

First, Jetpack is doing it wrong, yup. We should just ask for the excerpt we want using Core functions (get_the_excerpt( $post );), which works as of WP 4.5 outside of the loop. ( https://github.com/Automattic/jetpack/pull/8510 )

Second, noting get_the_excerpt's relatively new ability to accept a post argument, the default filter adds wp_trim_excerpt, which has not been updated to accept this new usage of get_the_excerpt, so it'll error out on it's own (or use the global $post data instead of the specified $post).

Try running

$post = get_post( [ID of an attachment] );
get_the_excerpt( $post );

and it'll throw a notice still.

Patch incoming. Marking as issue since 4.5 based on when the $post arg was added to get_the_excerpt

Last edited 6 years ago by kraftbj (previous) (diff)

@kraftbj
6 years ago

Updating wp_trim_excerpt to accept a post object

#19 @dd32
6 years ago

Yep 42814.diff will also avoid the warning, as it prevents calling get_the_content( '' ) which is the actual underlying function which requires to be in the loop

However, it still has the same issue - It avoids it by simply using the full post_content directly rather than the processed content which respects <!--nextpage--> and <!--more--> tags.
While you're right, that using the passed $post context helps and avoids this code branch in Jetpack, it doesn't fix it overall I don't think

#20 @kraftbj
6 years ago

That's fair.

So yes, one thing that needs to happen is for get_the_content to work outside the loop.

Another is, specific to the excerpt, Core incompletely adding support for get_the_excerpt working outside the loop, which my patch addresses (could say incompletely since get_the_content($post) would be ultimately the best).

Not sure if it is best to conflate both into this ticket or break them out to separate issues. At least with the excerpt issue, it is truly a bug (should have been done in 4.5) while get_the_content never intended to work outside the loop, so is more of an enhancement.

By itself, the excerpt patch not using processed content should be fine in the majority of cases, with the major exception of when the excerpt length is longer than the content before a more/nextpage jump when getting the excerpt outside of the loop, which would have previously returned the wrong excerpt (I think), since wp_trim_excerpt would only be acting on the global.

#21 @kraftbj
6 years ago

  • Milestone changed from Awaiting Review to 4.9.3

I'm bumping this to 4.9.3 so it can get some attention, specifically for resolving what (IMO) was left undone in the work that shipped in 4.5. I'm presuming that 1. I'm accurately following the code and this is functionality that's now a bug because it was missing from 4.5 and 2. having get_the_content working outside of the loop is an enhancement that should go in via another ticket.

This ticket was mentioned in Slack in #core by desrosj. View the logs.


6 years ago

This ticket was mentioned in Slack in #core by kraft. View the logs.


6 years ago

#24 @Greg Raven
6 years ago

I’m seeing the same issue on one of my WordPress sites. When I use any version of PHP up to 7.1, the page is fine. When I switch to 7.2, I get this error message:

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

So, I compared post-template.php from one of my sites that works fine under PHP 7.2 and the one giving me the error. Each is running version 4.9.2 WordPress. However, there are subtle differences between the two post-template.php files! None of the differences is anywhere near line 284, but I’m still baffled how two supposedly identical files can have different content.

#25 follow-up: @Kelderic
6 years ago

I just ran into this when I began testing with PHP 7.2. In my <head> section of my theme, I call get_the_excerpt as part of Open Graph meta tags. I have tried passing the post ID using get_the_ID, and passing $post, but I can't get rid of the error.

If we add:

if ( ! is_array($pages) ) {  
        $pages = []; 
}

At line 283 of post-template.php, we correct the issue. Long term, we need to check that all expected arrays are really arrays, and convert NULL values to empty arrays before calling count().

Last edited 6 years ago by Kelderic (previous) (diff)

This ticket was mentioned in Slack in #core by williampatton. View the logs.


6 years ago

#27 @williampatton
6 years ago

  • Milestone changed from 4.9.3 to 4.9.4

Moving to next release milestone.

#28 @internetwerk
6 years ago

Update to WordPress 4.9.3, same problem: "Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/web8/htdocs/wp-includes/post-template.php on line 284"

#29 @avcascade
6 years ago

Also affected by this issue. Not using Jetpack, but WordPress site I tested PHP 7.2.x with is generating OpenGraph meta tags.

#30 @dd32
6 years ago

  • Milestone changed from 4.9.4 to 4.9.5

Bumping, 4.9.4 has been released.

#31 @swissspidy
6 years ago

Looking at 42814.diff, this is something covered by #36934.

#32 @swissspidy
6 years ago

#43368 was marked as a duplicate.

#33 @jrf
6 years ago

#43374 was marked as a duplicate.

#34 @pkwooster
6 years ago

Same issue on 4.9.4 multi-site with Jetpack and PHP 7.2. Backoff to 7.1 resolved the issue for now.

#35 in reply to: ↑ description @adelsonbn
6 years ago

I was able to solve the problem on my website: Disabling Publicize connections and Sharing buttons in the Jetpack plugin.

This ticket was mentioned in Slack in #core by audrasjb. View the logs.


6 years ago

#37 @audrasjb
6 years ago

  • Milestone changed from 4.9.5 to 4.9.6

Bumping to 4.9.6 due to 4.9.5 beta release.

#38 @SergeyBiryukov
6 years ago

  • Component changed from Formatting to Posts, Post Types

#39 @SergeyBiryukov
6 years ago

#43600 was marked as a duplicate.

#40 @gsarig
6 years ago

On my case, it happens on a different scenario: on a WooCommerce eshop I created a price filter. The filter works fine with no errors or warnings. If I select a price range that has no results, though, I get the warning, even if everything else seems OK and the actual content shows the "No products were found matching your selection." message, as it should. Adding

if ( ! is_array($pages) ) {  
        $pages = []; 
}


doesn't help on my case, because then I get another Notice: Undefined offset: -1 ...on line 289, which is

$content = $pages[$page - 1];

What seems to solve it for me is simply changing the line

if ( $page > count( $pages ) )

to that:

if ( $pages && $page > count( $pages ) )

#41 @tasmer
6 years ago

Hello, I get the same issue on 4.9.1 with PHP 7.2.1.

In my case I call get_the_excerpt () from the hook wp_head and I get this warning when the excerpt is empty.

The same observation as @Kelderic and @gsarig

We should set the global $pages to an empty array if is null, because get_the_excerpt can be call outside the main loop.

$pages = is_array ($pages)? $pages: array ();

at line 262 of post-template. PHP (inside the get_the_content function)

#42 follow-up: @FPCSJames
6 years ago

This also occurs when calling wp_calculate_image_srcset(). Changing line 1206 to:

if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) {

fixes the issue.

#43 in reply to: ↑ 42 @SergeyBiryukov
6 years ago

Replying to FPCSJames:

This also occurs when calling wp_calculate_image_srcset().

That one's already fixed in #43201, the fix will ship with 4.9.5.

#44 follow-up: @qbaf
6 years ago

Upgraded today to 4.9.5 and no changes

#45 in reply to: ↑ 44 @cezariuszmarek
6 years ago

Replying to qbaf:

Upgraded today to 4.9.5 and no changes

Update 4.9.5 fixed #43201, not this one.

#46 in reply to: ↑ description @yashparmar71
6 years ago

Replying to internetwerk:

Warning with PHP 7.2:

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

if get this error
you must be try this it work very nice

while (have_posts()) { the_post();

}

Last edited 6 years ago by yashparmar71 (previous) (diff)

This ticket was mentioned in Slack in #core by desrosj. View the logs.


6 years ago

#48 @davisshaver
6 years ago

If get_the_content() should not be called outside the loop, could we patch by adding a conditional check to the top? The function would operate as-is but would no longer throw a PHP warning.

<?php
        if ( ! in_the_loop() ) {
                return '';
        }

This is similar to how get_post() behaves.

<?php
        $post = get_post( $post );
        if ( empty( $post ) ) {
                return '';
        }

For now, I have patched in implementation like so:

<?php
        if ( in_the_loop() && ! has_shortcode( get_the_content(), 'custom-shortcode' ) ) ) {
                echo 'do something';
        }
Last edited 6 years ago by davisshaver (previous) (diff)

#49 @f_monts
6 years ago

How to fix this? It's spamming millions of rows in our logs

This ticket was mentioned in Slack in #core by desrosj. View the logs.


6 years ago

This ticket was mentioned in Slack in #core by desrosj. View the logs.


6 years ago

This ticket was mentioned in Slack in #core by desrosj. View the logs.


6 years ago

#53 @desrosj
6 years ago

  • Milestone changed from 4.9.6 to 4.9.7

Punting to 4.9.7.

#54 @Abigailm
6 years ago

Seeing the same issue on one of my sites after upgrade from PHP 7.1 to PHP 7.2. The error is sporadic on a very busy site, generating about 40 warnings per day in error logs on a site that is getting tens of thousand of hits daily... so only triggered by something infrequent. The site does NOT run jetpack.

I have been able to replicate the error. The error corresponds to certain user search requests on the site. If I find the triggering GET request and repeat the search (entering the same terms in the "search" field from any page on the site) -- then the error recurs. But it only happens in some instances -- not all searches. So I can't simply enter random searches and create the error. The site is running the Relevansii plugin so I will report the problem in the support forum there as well. (I don't know enough about how relevanssi modifies the core wordpress search function to determine the source of the problem).

Last edited 6 years ago by Abigailm (previous) (diff)

#55 @ocean90
6 years ago

#44140 was marked as a duplicate.

#56 @desrosj
6 years ago

  • Milestone changed from 4.9.7 to 4.9.8

Moving all tickets in 4.9.7 to 4.9.8.

#57 @juergen74
6 years ago

For me this seem to be a problem of Themes or Plugins calling the Function get_the_content() outside of the Loop.

So if you call it outside the loop the global $pages = null

There are some easy fixes for this error: Don't call the function from outside of the loop! :) And if you see a theme or plugin that is doing that, ask the developers to fix it.

or we could check $pages for null and return an empty string right at the begining of the function.

function get_the_content( $more_link_text = null, $strip_teaser = false ) {
	global $page, $more, $preview, $pages, $multipage;

        if (is_null($pages)) { return ''; }    // new line

	$post = get_post();

....

#58 @Clorith
6 years ago

#44297 was marked as a duplicate.

This ticket was mentioned in Slack in #core by pbiron. View the logs.


6 years ago

#60 @pento
6 years ago

  • Milestone changed from 4.9.8 to 4.9.9

4.9.8 has hit RC, moving to 4.9.9.

#61 in reply to: ↑ description ; follow-up: @volkerg
6 years ago

On our website, we recognize the same error:

http://w-k-o.de/das-praesidium/ shows: Warning: count(): Parameter must be an array or an object that implements Countable in /homepages/28/d689728036/htdocs/clickandbuilds/WorldKennelOrganization/wp-includes/post-template.php on line 284

It is a multilingual wordpress website with latest polylang, avada theme, and other updates. The error occures after updating the components. On php 5.6 and on php 7.1 the german pages are not shown, the english pages are shown fine.

Switching back to php 7.2.8 I got the same error again. Warning is shown, german pages are not shown, english pages run fine.

If needed I can restore my backup and check if the error occures before updating, just changing the php versions or if it is result of an update.

I am using WP 4.9.8 running AVADA Child Theme

Replying to internetwerk:

Warning with PHP 7.2:

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

---> https://www.blogseye.com/convert-a-web-page-to-a-wordpress-theme-in-5-minutes/
---> https://neu.internetwerk.de/business-webhosting/bestellformular/

Last edited 6 years ago by volkerg (previous) (diff)

#62 in reply to: ↑ 61 @volkerg
6 years ago

08.08.2018: After restoring the website, I am still using php 7.2.8 no error occured. I am using WP 4.9.8 and MySQL 5.5.60

I am a little bit afraid of updating the plugins.

07.08.2018: This fixes the error (edit post-template.php line 284), but the german pages are still not shown:

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;
} give them the highest numbered page that DOES exist

Replying to volkerg:

On our website, we recognize the same error:

http://w-k-o.de/das-praesidium/ shows: Warning: count(): Parameter must be an array or an object that implements Countable in /homepages/28/d689728036/htdocs/clickandbuilds/WorldKennelOrganization/wp-includes/post-template.php on line 284

It is a multilingual wordpress website with latest polylang, avada theme, and other updates. The error occures after updating the components. On php 5.6 and on php 7.1 the german pages are not shown, the english pages are shown fine.

Switching back to php 7.2.8 I got the same error again. Warning is shown, german pages are not shown, english pages run fine.

If needed I can restore my backup and check if the error occures before updating, just changing the php versions or if it is result of an update.

I am using WP 4.9.8 running AVADA Child Theme

Replying to internetwerk:

Warning with PHP 7.2:

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

---> https://www.blogseye.com/convert-a-web-page-to-a-wordpress-theme-in-5-minutes/
---> https://neu.internetwerk.de/business-webhosting/bestellformular/

Last edited 6 years ago by volkerg (previous) (diff)

#63 @pento
6 years ago

  • Milestone changed from 4.9.9 to 5.1

#64 @rogerlos
5 years ago

Just as a sanity check, as a developer I would "naturally" (ie, I'm probably doing it wrong) expect that if I have a legit post object in my possession, I should be able to call any get_the_ functions using that post_id (or by handing the function the post object).

The reason: I want WordPress to apply the filters normally applied to post_content to the post my code has grabbed in hopes of "normalizing" my function's output to match other content on the site.

This is also tricky in that get_the_excerpt does not fail if there is content in post_excerpt. I call get_the_excerpt sometimes in hopes that I get back content even if post_excerpt is empty via its "grab some post content" feature.

My opinion, worth exactly what you're paying for it, is that there ideally should not be any "within the loop" only functions, just like there should be no functions which only echo content without option to get back the results...

Edited to add that I've been doing this for years, mind you without having read every line of WP's source, but I've always had the (mistaken) understanding that get_the functions exist specifically to get desired content outside of the loop context. The get_the naming does lend itself to my interpretation, though.

Last edited 5 years ago by rogerlos (previous) (diff)

#65 @Asphar
5 years ago

Hi everyone,

I'm a WordPress user and I have been watching this thread since July 2, 2018, when this warning first appeared on one of the websites I admin.

Since I am not a "real" developer, I was reluctant to touch WordPress core files, thinking that might somehow mess up automatic updates in the future... So as this thread said that there was already a patch for this problem and it was planned as a milestone for the next release, I thought I'd just wait. But it was pushed back and further back again, from being planned to be fixed in WordPress 4.5 to currently planned to get fixed in WordPress 5.1, if I understand this correctly...?

Today I just looked at the 42814.patch file provided by Shital Patel and deleted and added the corresponding lines by hand to post-template.php, because I don't know how else to apply this - SVN I presume? As I said, I'm not a real developer. Anyway, that worked, thank you, Shital!

Just wanted to give my feedback, that from a user's point of view, I don't really understand why this fix is being pushed back again and again. This thread is 12 months old now. There are users out there that are seeing this annoying warning message and their only option is to edit core WordPress files by hand, quite likely not knowing what they are doing... I really don't understand why a bug known for a year with a working patch is not commited to the production version...

Cheers,
André

#66 @pento
5 years ago

#45430 was marked as a duplicate.

#67 @jtibbles
5 years ago

  • Keywords dev-feedback added; has-patch removed

I have this error running WP 4.9.8, Php 7.2 and without Jetpack.
The error occurs for me using a plugin called WP-ImmoMakler (an estate agent with automated list of properties).
It only occurs on a "single" post page using the custom post type given by the plugin. If I create a normal post I don't see the error. This indicates to me an issue with either the way in which the new post is automatically created by the plugin, or an error on custom post types. Or both.

@spacedmonkey
5 years ago

#68 @spacedmonkey
5 years ago

I spent the evening looking this issue and #36934 as they related.

Looking at this change, it seems impossible to use get_the_content() all the globals to be setup and will never work as expected in this context. I believe in the only way to fix this is to use post_content directly from the $post. This maybe a major breaking change, but for the fix I believe it is worth it.

I have added a patch 42814.2.diff.

#69 @spacedmonkey
5 years ago

  • Milestone changed from 5.1 to 5.0.1

As this is a issue that will effect PHP 7.3, I am changing the milestone to 5.0.1.

#70 @spacedmonkey
5 years ago

  • Keywords has-patch 2nd-opinion needs-testing added

#71 @spacedmonkey
5 years ago

  • Keywords php73 added

Adding the PHP73 keyword, as this will be affect that version of as well and will be a bigger problem there.
This change, will need to be back ported to all the way back to WP 4.5, as that is original error came in.

#72 @swissspidy
5 years ago

@spacedmonkey I don't think it's impossible to use get_the_content(). Last time I worked on a patch there I felt it was really close. Also quite a change, but perhaps not as big as not using get_the_content() at all anymore.

Since both #36934 and this one are about the same issue, perhaps we can close this one as a duplicate? Alternatively, we could run with 42814.2.diff as a temporary fix and then continue working on getting rid of the globals in #36934

@spacedmonkey
5 years ago

#73 @spacedmonkey
5 years ago

@swissspidy I have been working on a solution for both problems. 42814.3.diff is what I came up with, as it basically removes the need to the globals as those varibles are generated when need them. The issue is, what if people have modified the globals. Maintaining the backwards compat is hard here. I think my patch does it...

Will to move this chat over too #36934 people think that is a better place for it.

@spacedmonkey
5 years ago

#74 @spacedmonkey
5 years ago

After a chat with @swissspidy I have updated the patch. See 42814.4.diff that passes $post to all the functions that require it.

I just need feedback now.

#75 @pento
5 years ago

  • Milestone changed from 5.0.1 to 5.0.2

#76 @pento
5 years ago

  • Milestone changed from 5.0.2 to 5.0.3

#77 @sniper29a
5 years ago

I get this error whenever I publish a new post. It is still in WP5.

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

Warning: Cannot modify header information - headers already sent by (output started at .../wp-includes/post-template.php:284) in .../wp-admin/post.php on line 209

This ticket was mentioned in Slack in #core by desrosj. View the logs.


5 years ago

This ticket was mentioned in Slack in #core by desrosj. View the logs.


5 years ago

#80 @desrosj
5 years ago

  • Milestone changed from 5.0.3 to 5.1

This still needs testing and review. Punting to 5.1.

#81 @spacedmonkey
5 years ago

  • Keywords needs-refresh needs-unit-tests added; needs-testing removed

This patch needs refreshing and unit tests.

#82 @pento
5 years ago

  • Milestone changed from 5.1 to 5.2

Bumping to 5.2, I like the general direction of 42814.4.diff, but it's going to need some more time.

#83 @ocean90
5 years ago

#46148 was marked as a duplicate.

#84 @swissspidy
5 years ago

#46175 was marked as a duplicate.

#85 @1naveengiri
5 years ago

@internetwerk Good catch,

It is just to notify.
I have noticed this warning when I use get_the_excerpt($post_id) outside the loop on Init or wp action hook.
the function seems not throwing warning when I am using it on wp_head.

#86 @DrLightman
5 years ago

I just upgraded from PHP 5.6.40 to PHP 7.3 and I started to get the same warning too on WP 4.9.8

I'm posting my xdebug's stack trace hoping it can be of any help. In my case the cause can be related to /amp/ plus /glue-for-yoast-seo-amp/ plugins.

PHP Warning:  count(): Parameter must be an array or an object that implements Countable in /var/www/html/wp-includes/post-template.php on line 284
PHP Stack trace:
PHP   1. {main}() /var/www/html/index.php:0
PHP   2. require() /var/www/html/index.php:17
PHP   3. require_once() /var/www/html/wp-blog-header.php:19
PHP   4. do_action() /var/www/html/wp-includes/template-loader.php:12
PHP   5. WP_Hook->do_action() /var/www/html/wp-includes/plugin.php:453
PHP   6. WP_Hook->apply_filters() /var/www/html/wp-includes/class-wp-hook.php:310
PHP   7. amp_render() /var/www/html/wp-includes/class-wp-hook.php:286
PHP   8. amp_render_post() /var/www/html/wp-content/plugins/amp/amp.php:284
PHP   9. AMP_Post_Template->load() /var/www/html/wp-content/plugins/amp/amp.php:333
PHP  10. AMP_Post_Template->load_parts() /var/www/html/wp-content/plugins/amp/includes/templates/class-amp-post-template.php:200
PHP  11. AMP_Post_Template->verify_and_include() /var/www/html/wp-content/plugins/amp/includes/templates/class-amp-post-template.php:211
PHP  12. include() /var/www/html/wp-content/plugins/amp/includes/templates/class-amp-post-template.php:441
PHP  13. AMP_Post_Template->load_parts() /var/www/html/wp-content/themes/my-theme/amp-template-0.7/single.php:19
PHP  14. AMP_Post_Template->verify_and_include() /var/www/html/wp-content/plugins/amp/includes/templates/class-amp-post-template.php:211
PHP  15. include() /var/www/html/wp-content/plugins/amp/includes/templates/class-amp-post-template.php:441
PHP  16. do_action() /var/www/html/wp-content/plugins/amp/templates/html-start.php:19
PHP  17. WP_Hook->do_action() /var/www/html/wp-includes/plugin.php:453
PHP  18. WP_Hook->apply_filters() /var/www/html/wp-includes/class-wp-hook.php:310
PHP  19. YoastSEO_AMP_Frontend->extra_head() /var/www/html/wp-includes/class-wp-hook.php:286
PHP  20. do_action() /var/www/html/wp-content/plugins/glue-for-yoast-seo-amp/classes/class-frontend.php:253
PHP  21. WP_Hook->do_action() /var/www/html/wp-includes/plugin.php:453
PHP  22. WP_Hook->apply_filters() /var/www/html/wp-includes/class-wp-hook.php:310
PHP  23. WPSEO_OpenGraph->description() /var/www/html/wp-includes/class-wp-hook.php:286
PHP  24. get_the_excerpt() /var/www/html/wp-content/plugins/wordpress-seo/frontend/class-opengraph.php:603
PHP  25. apply_filters() /var/www/html/wp-includes/post-template.php:397
PHP  26. WP_Hook->apply_filters() /var/www/html/wp-includes/plugin.php:203
PHP  27. wp_trim_excerpt() /var/www/html/wp-includes/class-wp-hook.php:288
PHP  28. get_the_content() /var/www/html/wp-includes/formatting.php:3308

So it seems that it's tiggered by get_the_excerpt()

It does an return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); at the end.

The default WP add_filter( 'get_the_excerpt', 'wp_trim_excerpt' ); gets executed.

wp_trim_excerpt uses get_the_content('') to build an excerpt when the post has none filled by the author.

And the line 284 of thw Warning refers at an instruction of get_the_content('').

Which function should init the global $page and $pages variables and it fails in this flow? Maybe it's the visibility that fails?

Last edited 5 years ago by DrLightman (previous) (diff)

#87 @DrLightman
5 years ago

My personal no-core """fixes""" have been:

1 - make sure a post as an explicit excerpt

2 - doing a remove_filter( 'get_the_excerpt', 'wp_trim_excerpt' ); in theme's functions.php or a custom plugin to stop the automatic excerpt's generation for posts without an explicit excerpt.

@spacedmonkey
5 years ago

#88 @spacedmonkey
5 years ago

  • Keywords has-unit-tests added; needs-refresh needs-unit-tests removed

In 42814.5.diff I fix a couple of issues, with incorrect use of compact function.

There are now also tests.

@spacedmonkey
5 years ago

@spacedmonkey
5 years ago

#89 @spacedmonkey
5 years ago

In 42814.8.diff I have added improved tests for get_the_excrept and get_the_content, hopefully this is enough for this to get merged.

#90 @wetapplemedia
5 years ago

This is also affecting Wordpress using PHP 7.3.2.

Version 0, edited 5 years ago by wetapplemedia (next)

#91 @boonebgorges
5 years ago

The approach in 42814.8.diff looks good to me. 42814.6.diff (auto-numbering is off because of some missing patches!) is a formatting and documentation cleanup.

Last edited 5 years ago by boonebgorges (previous) (diff)

@boonebgorges
5 years ago

#92 @jzlcdh
5 years ago

This also seems to be affecting the Polylang plugin version 2.5.2 in Wordpress 5.1
\wp-includes\post-template.php on line 293

If this is something different as it has a different line number or I should raise it as a bug with Polylang or if you need more testing or more details please let me know.

#93 @spacedmonkey
5 years ago

@boonebgorges thanks for the formatting. But your patch seems to be missing some of the new unit test files. My patch is 15k and ours is 10k. Can we make sure those tests are there part of commit please.

One things that I thought, is this will now mean that if you are post and page 2 of a multipage post and you have content from post post in say the sidebar, you will also see page two it's content as well, as page is defined as a query var. Not sure this is something we can fix.

@boonebgorges
5 years ago

#94 @boonebgorges
5 years ago

Sorry about that. I've regenerated the patch: 42814.9.diff

#95 follow-up: @spacedmonkey
5 years ago

I think we looking good with 42814.9.diff. Any chance this could be merged for 5.2? cc @boonebgorges @swissspidy

#96 in reply to: ↑ 95 @reelism
5 years ago

Replying to spacedmonkey:

I think we looking good with 42814.9.diff. Any chance this could be merged for 5.2? cc @boonebgorges @swissspidy

Hope that it's ok to ask here - I've got many of the issues listed above, and site went down today because of it and server-limits. I'm dependent on jetpack, is there a way I (as a non dev, with a 99% finished WP site) can either integrate these fixes into WP before it's accepted to 5.2, or install a 5.2 nightly to fix?

This ticket was mentioned in Slack in #core by spacedmonkey. View the logs.


5 years ago

#98 @kraftbj
5 years ago

@reelism - On the Jetpack topic, can you open an issue at https://github.com/automattic/jetpack/ with what specifically you're seeing? I thought I squashed why Jetpack was generating those awhile ago.

As for the patch, running through some tests with it all look good.

#99 @boonebgorges
5 years ago

  • Owner set to boonebgorges
  • Resolution set to fixed
  • Status changed from reopened to closed

In 44941:

Posts: Avoid the use of globals in get_the_content() and related functions.

This changeset introduces $post parameters to get_the_content() and
wp_trim_excerpt(). When a $post object is passed to one of these functions,
the functions will operate on the data from that object, rather than from the
post globals ($authordata, $page, etc). This ensures that the functions work
in a predictable manner when used outside of the regular post loop.

The global-mismatch problem is surfaced in cases where get_the_excerpt() is
called outside of the post loop, on posts that don't have a defined excerpt. In
these cases, the post globals - used to generate a fallback excerpt - may refer
to the incorrect object, resulting in PHP notices or other unpredictable
behavior. See #36934 for a related issue.

Props spacedmonkey, kraftbj, Shital Patel.
Fixes #42814.

#100 @david.binda
5 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

Testing the r44941 on some in-house and client's code on WordPress.com, I run into issues with certain implementations.

To be honest, the sample failing code does not feel right, but it has been working up until applying the r44941.

Here is an example failing implementation in a form of a unit test:

<?php
    public function test_get_the_excerpt_after_setup_postdata_without_global_post() {
        $p1 = self::factory()->post->create_and_get(
            array(
                'post_content' => 'Foo',
            )
        );

        $post_object = get_post( $p1->ID );
        setup_postdata( $post_object );

        $this->assertSame( 'Foo', get_the_content() );
    }

You might have noticed, that in order to make the code working properly, it either needs to override the global $post with $post_object, or pass the $post_object to the get_the_content function (taking advantage of the new param of the function).

From my experience, forgetting to set the global $post value to whatever post is being processed inside a loop, or forgetting to call setup_postdata in there is quite common, and possibly easily overlooked, as call like get_the_content() simply works (despite the issues described in this ticket).

I've run into several pieces of code which were refactored the way the global $post overriding was removed or broken, w/o failing the rest of the implementation until the r44941.

It feels like this changeset has a capability of breaking some existing code leading to content not being displayed, which is unfortunate. Is there any chance to rethink the approach, or are we okay with this backward compatibility breaking change?

#101 @spacedmonkey
5 years ago

@davidbinda Thanks for your feedback.

Have you looked into this test why it now fails. If this fails $this->assertSame( 'Foo', get_the_content() );, what is the value of get_the_content() / what post does it come from?

I think that maybe, this should be another ticket, as this ticket already has 100 comments on it.

#102 @spacedmonkey
5 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

After testing your unit test @davidbinda I have confirmed it is invalid. I am not sure how was it working before, it is invalid. For that test to pass it would need to the global $post object. The test would have to look like this

        /**
         * @ticket 42814
         */
        public function test_ge_the_content_after_setup_postdata_without_global_post() {
                global $post;
                $p1 = self::factory()->post->create_and_get(
                        array(
                                'post_content' => 'Foo',
                        )
                );

                $post_object = get_post( $p1->ID );
                $post = $post_object;
                setup_postdata( $post_object );

                $this->assertSame( 'Foo', get_the_content() );
        }

For that reason, I am re-closing this ticket.

#103 in reply to: ↑ 16 @slamorte
5 years ago

Replying to Cibulka:

In my case, it was a call to get_the_excerpt(), when the page had none. I have fixed it roughly this way:

global $post;
$excerpt = !empty($post->post_excerpt) ? get_the_excerpt() : null;

PHP 7.2 as well.

WordPress 5.0.3 and PHP 7.2 I had the same error when getting an empty excerpt.

Fixed with your code.

#104 @SergeyBiryukov
5 years ago

#46445 was marked as a duplicate.

#105 @SergeyBiryukov
5 years ago

#46983 was marked as a duplicate.

#106 @spacedmonkey
5 years ago

#36934 was marked as a duplicate.

#107 @lucasbustamante
5 years ago

As the buddy above mentioned, I have also stumbled upon this while writing tests. I was creating a post using a factory and overriding $GLOBALS[ 'post' ].

Calling setup_postdata($post->ID) fixed it for me. Just saying this to help understand in which context this warning might pop up.

#108 in reply to: ↑ 25 ; follow-up: @jcdev518
5 years ago

Replying to Kelderic:

I just ran into this when I began testing with PHP 7.2. In my <head> section of my theme, I call get_the_excerpt as part of Open Graph meta tags. I have tried passing the post ID using get_the_ID, and passing $post, but I can't get rid of the error.

If we add:

if ( ! is_array($pages) ) {  
        $pages = []; 
}

At line 283 of post-template.php, we correct the issue. Long term, we need to check that all expected arrays are really arrays, and convert NULL values to empty arrays before calling count().

Re: ticket #42814

I know this has been marked as "completed" but I ran into a similar issue with PHP 7.2 this many months later.
Same error, but on line 310 of post-template.php after calling get_the_content() outside of the main loop. This is in a singular page template where $post is already global.

Although it seemed redundant, I wrapped the call inside the loop:

<?php
while ( have_posts() ): 
  the_post();

  get_the_content();

endwhile;

and it fixed the error, as it's no longer trying to count() a null value in {{{#!php

$elements['pages'];

FYI this is now on WP 5.2.1 - thought I'd mention it as a way to fix without modifying core.

Last edited 5 years ago by jcdev518 (previous) (diff)

#109 @Abigailm
5 years ago

This comment is also added for informational purposes:

I am also still seeing this error, now with a reference to line 310 (PHP 7.3, WP 5.2.1).

In my case it is tied to the enhanced search plugin, Relevanssi -- and occurs if the plugin option for "Create custom search result snippets" is enabled. This has been a consistent issue for me --- but I don't know whether it should be seen as a problem with the wordpress core template or with the coding of that particular feature of the plugin.

The error appears to be tied to this line of code in the plugin:

	/** This filter is documented in wp-includes/post-template.php */
	$content = apply_filters( 'the_content', $content );

So basically, the plugin is calling the apply_filters function that is coded into post-template.php ... and somewhere along the line that generates the PHP "implements Countable" warning in some (but not all) use cases.

#110 @tinamar
5 years ago

I didn't see this posted. So, here's the info on the change to count() that occurred in php 7.2:
https://wiki.php.net/rfc/counting_non_countables

This ticket was mentioned in Slack in #core-editor by hosseinhashemi. View the logs.


5 years ago

This ticket was mentioned in Slack in #core by hosseinhashemi. View the logs.


5 years ago

#113 in reply to: ↑ 108 @SergeyBiryukov
5 years ago

Replying to jcdev518:

I know this has been marked as "completed" but I ran into a similar issue with PHP 7.2 this many months later.
Same error, but on line 310 of post-template.php after calling get_the_content() outside of the main loop. This is in a singular page template where $post is already global.

Thanks! I've seen this mentioned on support forums as well, and created a follow-up ticket: #47824.

Although it seemed redundant, I wrapped the call inside the loop:

<?php
while ( have_posts() ): 
  the_post();

  get_the_content();

endwhile;

and it fixed the error, as it's no longer trying to count() a null value in {{{#!php

$elements['pages'];

Yes, that's the correct way to solve it for now.

#114 @SergeyBiryukov
4 years ago

In 48114:

Posts, Post Types: Avoid a PHP warning when get_the_content() is called outside of the loop.

This ensures that $pages and other globals are only used after they have been set up in setup_postdata().

Follow-up to [44941].

Props tessawatkinsllc, dontdream, spacedmonkey, squarecandy, davidbaumwald, SergeyBiryukov.
Fixes #47824. See #42814.

This ticket was mentioned in Slack in #core by helen. View the logs.


3 years ago

Note: See TracTickets for help on using tickets.