So strange result of wp_query and have_posts

I’ve tested some piece of simple code, but the result is so so strange.

Test 1:

Read More
$featured_posts = new WP_Query( $query_args );
while ($featured_posts->have_posts()) {
    $featured_posts->the_post();
    the_title(); echo '<br>';           
}
echo 'End: "' . $featured_posts->have_posts() . '"'; // have_post() is TRUE, WHY?

Test 2:

$featured_posts = new WP_Query( $query_args );
$have_posts = $featured_posts->have_posts();
while ($have_posts) {
    $featured_posts->the_post();
    the_title(); echo '<br>';           
    $have_posts = $featured_posts->have_posts();
}
echo 'End: "' . $have_posts . '"'; // false -> I think false is right.              
echo 'End: "' . $featured_posts->have_posts() . '"'; // but still TRUE, WHY?

Am I missing anything?

Related posts

1 comment

  1. If we look at have_posts() in source, we can see why this happens:

    function have_posts() {
        if ( $this->current_post + 1 < $this->post_count ) {
            return true;
        } elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
            do_action_ref_array('loop_end', array(&$this));
            // Do some cleaning up after the loop
            $this->rewind_posts();
        }
    
        $this->in_the_loop = false;
        return false;
    }
    

    When it reaches the end of the loop, it calls rewind_posts, which resets current_post back to -1, so the next call to have_posts will return true again.

    function rewind_posts() {
        $this->current_post = -1;
        if ( $this->post_count > 0 ) {
            $this->post = $this->posts[0];
        }
    }
    

Comments are closed.