Make sense of WordPress query functions

One of my most upvoted answers at WordPress Stack Exchange is for question about WP_Query vs query_posts() vs get_posts(). I think no other WordPress issue caused that many bugs and frustrations and this is one of the very few areas where I see even most experienced developers misstep.

So I’ve been coming back to my answer from time to time, because I didn’t feel entirely content with it. Telling people what to do relies on their memory (meh) and positive reinforcement. Unfortunately most people encounter way more crappy WordPress code around than good one. Mistakes in usage of query functions just get copied and used again and again for years.

At first I wanted to do extended table comparison between functions but I lost the fight with markup. My second take was grabbing Balsamiq Mockups and (after two or three takes that failed miserably) I came up with following flowchart.

Make sense of WP query functions

I put it under Creative Commons Attribution-ShareAlike so I can also post it at WPSE, so feel free to grab a copy as well.

And do tell if I got any details wrong. :)

Related Posts


  • Klemen #

    Comic Sans, really?
  • Heiner #

    Thank you for this overview! Some of our junior programmers have problems with the query functions of WP.
  • Rarst #

    @Klemen Get off my back. :) It's what Mockups use by default and it's a bother to change (really bother - like in manually editing XML configuration file somewhere). @Heiner You are welcome. :) Tech them to write awesome WP code and spread good practices around.
  • Rakesh Kumar #

    This errors really annoy me and I realize that if were a developer may i can fix these problem. By the way my theme gives an error that header could not be modify!!!. What is that?
  • Rarst #

    @Rakesh Kumar Can be many things, please use http://wordpress.stackexchange.com/ or official support forums to ask your question.
  • Charleston #

    This is my first encounter of wordpress stack exchange and I must say that your illustration do clear up some of my query. Thanks for the info again Rarst.
  • finchamgroves #

    That's really great! I've been going around in circles for hours on the differences between these queries . At last something clear! There do seem to be variations in how people set up a new instances of WP_Query(). Is just this OK? new WP_Query() Some people seem to use this and I'm not sure why. $myqueryname = $wp_query; $wp_query = null; $wp_query = new WP_Query(); then off into loopy stuff...
  • Rarst #

    @finchamgroves Yep, that is fine. Like $some_variable = new WP_Query(); or $some_variable = new WP_Query($some_query_arguments);
    Some people seem to use this and I’m not sure why
    Because they probably want to change main Loop temporarily for some reason, but don't have a clue how to use query_posts() and wp_reset_query(). Which they should be using, instead of that contraption.
  • finchamgroves #

    @Rarst Many thanks. (It slows me down no end but I hate just using stuff without questioning why!)
  • Rarst #

    @finchamgroves No problem. :) And I highly recommend http://wordpress.stackexchange.com/ if you want to seriously improve your WordPress skills.
  • finchamgroves #

    Is there a difference between wp_reset_postdata() and rewind_posts() ? It's hard to find a comparison in the codex.
  • Rarst #

    @finchamgroves Entirely different functions. wp_reset_postdata() restores (or at least tries to) global $post variable to original post. rewind_posts() resets internal query counter (for example if you want to loop through same set of posts twice).
  • Marcko #

    Thank you for this overview
  • kaiser #

    One thing i really can't understand: Why wordpress devs *never* make use of the error object to help people. I don't know how often I've read the following sentence from "Otto", who's in the core dev team: "Then you're doing it wrong(tm)". I tend to say that I must have done something wrong, if the user couldn't do it right. If you take a look at one of my plugins "easy pagination deamon", then you'll find the function "help()" inside the class that notifies the user if the template tag wasn't placed right. It makes me close to angry, because i know there's - aside from the error class - another useful function inside core: "_doing_it_wrong( $function, $message, $version )" - /core-root/wp-includes/functions.php...
  • Rarst #

    @kaiser _doing_it_wrong is very recent addition (WP 3.1), I hadn't even seen mentions of it yet - stumbled on it by chance in source several days ago. So hopefully it will see more use in the future.
  • kaiser #

    @Rarst But afaik the error class is there since a much longer time... ;) Btw: Why don't you use threaded comments? Haven't ever seen a reply in the style you use it over here before.
  • Rarst #

    @kaiser Yep, but practice shows people commonly don't have a clue about WP_Error, how to catch it and what to do with it. Also it isn't returned consistently, same function can return that or something else on error under different conditions.
    Why don’t you use threaded comments? Haven’t ever seen a reply in the style you use it over here before.
    Custom made. :) I am not a huge fan of threaded comments, they tend to add a mess instead of solving it. I will probably revisit it when I get to updating the theme.
  • Chris Olbekson #

    I'm doing a talk at WordCamp Austin later this month about WP Query functions and would like to reference your flow chart. I was also thinking about updating it with pre_get_posts and is_main_query based on Nacin's recent presentation.
  • Vladimir #

    So what should I use? get_posts or wp_query I just prefer get_posts and not fully understood it is better
  • Rarst #

    @Vladimir None of the two is "better" (it's query_posts() that is worse than either). If there is no difference for the task - use the one of two that you are more comfortable dealing with.