What’s the difference between “get_posts” and “wp_get_recent_posts” when used with “setup_postdata”?

This might be a completely “I’m still new to WP” type question, but I ran into some interesting output when using get_posts() and wp_get_recent_posts() in a custom function I wrote with setup_postdata(). Here’s what I had in my functions.php file:

<?php
function getRecentPosts($total_posts = 2)
{
    $total_posts = intval($total_posts);
    global $post;

    $args = array(
        'posts_per_page' => $total_posts,
        'post_type'      => 'post',
        'post_status'    => 'publish'
    );
    $posts = get_posts($args);

    foreach ($posts as $post)
    {
        setup_postdata($post);
        echo '<div>';
            the_title();
        echo '</div>';
    }
    wp_reset_postdata();
}

Simple, right? And that function works great, throwing out title’s inside div tags perfectly. But when I replace lines 7-12 with the following:

    ...
    $args = array(
        'posts_per_page' => $total_posts,
        //'post_type'    => 'post',
        'post_status'    => 'publish'
    );
    $posts = wp_get_recent_posts($args);
    ...

…then the function doesn’t seem to “iterate” through the posts correctly, throwing out the first post it finds’ title over and over, much like if you don’t use global $post at the beginning of the function.

Why is this? Is there something different that wp_get_recent_posts() does that I do not yet understand.

1 Answer
1

If you look at the source of setup_postdata() you’ll find that it requires an object ($post), to be passed, not an array.

wp_get_recent_posts() (source), by default (for pre 3.1 backwards compatibilty) returns each post as an array. The second, optional argument, that can be passed to wp_get_recent_posts() can prevent this:

$posts = wp_get_recent_posts( $args, OBJECT_K )

(though any value other than ARRAY_A in the second argument will do).

Leave a Comment