When run a query with WP_Query method, I got an object. I understand that I can then do the loop to display stuffs. But, my goal is not to display anything, instead, I want to get some post data by doing something like "foreach...". How can I get an array of post data that I can loop through and get data?

  • 2
    An important difference to keep in mind between accessing post data directly versus using template tags is that filters are not applied to the data and some functionality may break.
    – Milo
    Dec 30, 2016 at 18:10

3 Answers 3


You should read the function reference for WP_Query on the WordPress codex. There you have a lot of examples to look at. If you don't want to loop over the result set using a while, you could get all posts returned by the query with the WP_Query in the property posts.

For example

$query = new WP_Query( array( 'post_type' => 'page' ) );
$posts = $query->posts;

foreach($posts as $post) {
    // Do your stuff, e.g.
    // echo $post->post_name;
  • 1
    None of the examples you link to demonstrates how to process posts, though. So it's good that you answered, pity they don't have it in the documentation. Another tip: If you're doing a match on a unique post you can use a function like this with 'posts_per_page'=>1 in args. function wp_queryfirstpost($args) { $q=new WP_Query($args); $pp=$q->get_posts(); $firstpost=false;if ($pp) $firstpost=$pp[0]; wp_reset_postdata(); return $firstpost; } Mar 21, 2014 at 9:38
  • @rofflox: You are a saint! Great for circumventing get_the_title/ID/younameit.
    – Vial
    Apr 30, 2015 at 17:39
  • 10
    You should use $query->posts instead, $query->get_posts() will trigger a re-running of the query parsing and additional unnecessary database queries
    – Tom J Nowell
    Nov 1, 2015 at 3:31
  • $query->get_posts(); is not working as expected. Not sure why but it returns fewer post than the query. See here: stackoverflow.com/questions/25395299/…
    – Laxmana
    Nov 12, 2016 at 17:05
  • 3
    This answer is plain wrong, when you create a new WP_Query with some arguments the method get_posts() is internally called right away and you SHOULD NOT CALL IT AGAIN! If you call it again as shown in the example above it will run a DIFFERENT query, depending on the arguments and results form the initial run (internal flags set, etc..), and can potentially return a different (smaller) set of results or no results at all. As TomJNowell and Laxmana suggested above one should use $query->posts to get the post data.
    – ivanhoe
    Dec 4, 2016 at 3:20

Actually, you don't need to refuse to use while() loop. Same WP_Post Object is already stored in post property:

$query = new WP_Query( $args );

if ( $query->have_posts() ) {

    // some code here if you want.

    while ( $query->have_posts() ) {


        // now $query->post is WP_Post Object, use:
        // $query->post->ID, $query->post->post_title, etc.

  • 4
    if is redundant. Jan 26, 2017 at 13:40
  • 3
    No, if is not redundant. In this exact case it is, but in most production situations, you have code to execute between the if and the while.
    – magi182
    Mar 27, 2017 at 15:36
  • 3
    @magi182 Which makes it redundant, in this exact case. People should learn when to use this.
    – frodeborli
    Apr 3, 2017 at 18:05
  • 4
    @frodeborli, The nice thing about statements that start with "people should" is that you can almost always substitute "people won't" and the statement still tests as true.
    – magi182
    Apr 6, 2017 at 3:28
  • 1
    @magi182 I could probably make a hundred nice to have code lines to complement the above code.
    – frodeborli
    Apr 8, 2017 at 21:01

you can also use get_posts( $args ) instead of wp_Query(), which will give you a list of posts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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