44

Is there a way I can retrieve an array of post ids queried from the following:

$latest = new WP_Query( array (
    'orderby'               => 'rand',
    'posts_per_page'        => 3
));

if ( $latest -> have_posts() ) : while ( $latest -> have_posts() ) : $latest -> the_post();

    get_template_part( 'templates/content', 'post' );

endwhile; endif; wp_reset_postdata();

Follow Up:

I used wp_list_pluck to retrieve an array of post ids:

$post_ids = wp_list_pluck( $latest->posts, 'ID' );

Then converted the array into a string using the implode function:

$post_ids_string = implode( ',', $post_ids );

Sorry for the ambiguous question.

3
  • rick, your question is ambiguous. Please be very clear what you want before posting a question. This will save everyone from answering irrelevant stuff. You actually need the post ID's returned in a string, not an array Oct 21, 2014 at 16:01
  • 1
    Your wp_reset_postdata should be inside not outside the if statement, otherwise you might reset post data when it hasn't been changed
    – Tom J Nowell
    Oct 21, 2014 at 16:19
  • 1
    If you're only wanting the IDs, you should seriously consider s_ha_dum's answer. That will return the IDs without also retrieving lots of other data from the database that you then throw away.
    – Chris Rae
    Feb 27, 2015 at 21:51

5 Answers 5

56

Try

$post_ids = wp_list_pluck( $latest->posts, 'ID' );

Read wp_list_pluck

1
  • 5
    This can be useful if you also need the whole data for each post, not just the posts ids. Otherwise, I'd go with @s-ha-dum's solution.
    – Marian
    Mar 31, 2017 at 8:09
119

Use the fields argument in your query.

fields (string) - Which fields to return. All fields are returned by
default. There are two other options: - 'ids' - Return an array of post IDs. - 'id=>parent' - Return an associative array [ parent => ID, … ].

https://developer.wordpress.org/reference/classes/wp_query/#return-fields-parameter

$latest = new WP_Query( array (
    'orderby'               => 'rand',
    'posts_per_page'        => 3,
    'fields' => 'ids'
));
var_dump($latest->posts);
3
  • 22
    This should be the accepted answer as it only queries the ID's making it a lot faster than quering everyhing and than 'plucking' (loop and re-storing) it in a new array. Feb 5, 2016 at 16:31
  • Perhaps you need to get IDs AFTER normal wp_query has already been executed, for example when you merge two queries afterwards and need ID's to exclude results from previous query.
    – trainoasis
    Aug 5, 2019 at 9:09
  • Thank you for sharing this solution, among the answers to this question, this is the most efficient. Nov 26, 2020 at 14:36
4

I suggest this solution

get_posts([
  'posts_per_page' => -1,
  'post_status' => 'publish',
  'post_type' => 'some-custom-post-type',
  'fields' => 'ids',
]);

and as return you have array with ids inside ;)

array (size=5)
  0 => int 81002
  1 => int 77885
  2 => int 77180
  3 => int 74722
  4 => int 73312
3

Using the solution from @s-ha-dum is economical if you only need to get the id's, and you don't have previous query object set.

Here is why:

switch ( $q['fields'] ) {
    case 'ids':
        $fields = "$wpdb->posts.ID";
        break;
    case 'id=>parent':
        $fields = "$wpdb->posts.ID, $wpdb->posts.post_parent";
        break;
    default:
        $fields = "$wpdb->posts.*";

Because in the case you only specify 'fields' => 'ids' nothing more you will get in return than the ID's.

If you would go with 'fields' => 'id=>parent' (Looks really funny) you will get also the parent ID's.

Any other way using 'fields' argument will not have any impact as of WordPress v4.7.

But in case you have the query as in the example wp_list_pluck will do the job.

0

Why not use the get_the_ID() function? Just sharing the loop code and it shows all post ids in the query.

// The Loop
    if ( $the_query->have_posts() ) {
        while ( $the_query->have_posts() ) {
            $the_query->the_post();     
                    
            echo '<li>' . get_the_ID() . '</li>';
        }
    } else {
        // no posts found
        $string = "no posts found";
    }
2
  • I think the goal was probably to get the IDs in an array to do something else with, not to actually display them. Using the loop for that feels like overkill.
    – Rup
    Jul 12, 2021 at 22:47
  • To add all the Ids 1 by 1 the loop is needed. The 'fields' => 'ids' is the best option to get all ids in an array.
    – Joy
    Jul 14, 2021 at 7:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.