have_posts()WP 1.5.0

Checks if global $wp_query has posts to process. Conditional tag.

This function is used in conjunction with the_post() function:

while ( have_posts() ) {
	the_post();

	the_title();
}

This function only works with the global $wp_query variable. Therefore, if you create a custom query, you need to use the working object method of the same name:

$query = new WP_Query( $args );

while ( $query->have_posts() ) {
	$query->the_post();

	// ...
}

wp_reset_postdata(); // IMPORTANT return global $post back
How have_posts() works in the loop.

Let's take this loop (code) as an example:

while ( have_posts() ) {
	the_post();
}

First of all, have_posts() checks if global $wp_query has at least one post:

  • If there are no posts, have_posts() runs hook loop_no_results, sets in_the_loop = false and returns false.

  • If there are posts, it returns true and the loop is started:

    1. On the first iteration of the loop, the_post() switches to the next post in the loop (for the first iteration it will be the first post in the loop) and sets that post to global $post.

      Also, the_post() sets other post data to global variables (see setup_postdata( $post )) and turn on in_the_loop = true property. See the_post() for details.

    2. In the second and subsequent iterations of the loop, have_posts() also checks if there is the next post in the loop, then the_post() switches to that next post and writes it to global $post as before.

    3. At the end of the loop, when there are no posts left in the loop, have_posts() runs loop_end hook, rewinds the loop to the original state (see rewind_posts()), disables the in_the_loop = false property and returns false - so the loop ends.
1 time — 0.000001 sec (speed of light) | 50000 times — 0.02 sec (speed of light) | PHP 7.2.5, WP 4.9.6

No Hooks.

Return

true|false.

  • false if there are no results to output.
  • true if there is something to output.

Usage

// not loop
if( have_posts() ){
	// ...
}

// loop
while ( have_posts() ) {
	the_post();

	// ...
}

Examples

1

#1 Determine whether there are records for output

The following example can be used to determine if there are posts to output and if there are, then run while part of the loop and output them:

<?php
if( have_posts() ){
	while( have_posts() ){
		the_post();
		// output code
	}
}
else {
	echo wpautop( 'No posts found for output.' );
}
?>
0

#2 Calling have_posts() inside a WordPress Loop

Calling have_posts () inside a WordPress Loop means an infinite loop. See the example:

while( have_posts() ){
	the_post();

	// Post output
	if( have_posts() ){ 
		// If this is the last post, the cycle will start again
		// Do something, if this is not the latest post
	}
}
0

#3 Check if there are posts in the current loop

If you want to check if there are more posts in the current loop, you can use the following function.

Use more_posts() instead of have_posts().

function more_posts() {
  global $wp_query;

  return $wp_query->current_post + 1 < $wp_query->post_count;
}

The function will return:

  • true - there are more posts in the query.
  • false - the last post is displayed.

Notes

  • Global. WP_Query. $wp_query WordPress Query object.

Changelog

Since 1.5.0 Introduced.

have_posts() code WP 6.4.3

function have_posts() {
	global $wp_query;

	if ( ! isset( $wp_query ) ) {
		return false;
	}

	return $wp_query->have_posts();
}