23

What is the difference between $GLOBALS['wp_the_query'] and global $wp_query?

Why prefer one over the other?

2
  • 2
    I would say global $wp_query just to answer your question in one line!
    – Sumit
    Mar 14, 2016 at 8:17
  • What is the difference? Mar 14, 2016 at 8:23

3 Answers 3

34

You have missed one, $GLOBALS['wp_query']. For all purposes, $GLOBALS['wp_query'] === $wp_query. $GLOBALS['wp_query'] is however better for readability and should be used instead of $wp_query, BUT, that remains personal preference

Now, in a perfect world where unicorns rule the world, $GLOBALS['wp_the_query'] === $GLOBALS['wp_query'] === $wp_query. By default, this should be true. If we look at where these globals are set (wp-settings.php), you will see the main query object is stored in $GLOBALS['wp_the_query'] and $GLOBALS['wp_query'] is just a duplicate copy of $GLOBALS['wp_the_query']

/**
 * WordPress Query object
 * @global WP_Query $wp_the_query
 * @since 2.0.0
 */
$GLOBALS['wp_the_query'] = new WP_Query();
/**
 * Holds the reference to @see $wp_the_query
 * Use this global for WordPress queries
 * @global WP_Query $wp_query
 * @since 1.5.0
 */
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];

The reason for doing it this way, is because WordPress saw the arrival of query_posts in version 1.5.

function query_posts($query) {
    $GLOBALS['wp_query'] = new WP_Query();
    return $GLOBALS['wp_query']->query($query);
}

As you can see, query_posts sets the main query object to the current custom query beign run. This breaks the integrity of the main query object, which gives you incorrect data, so anything that relies on the main query object is broken due to wrong data.

A way to counter this was to create another global to store the main query object, $GLOBALS['wp_the_query'] which was introduced in version 2.0.0. This new global hold the main query object and $GLOBALS['wp_query'] just a copy. Through wp_reset_query(), we could now reset $GLOBALS['wp_query'] back to the original main query object to restore its integrity.

But this is not a perfect world, and query_posts are the devil himself. Although thousands of warnings, people still use query_posts. Apart from breaking the main query, it reruns the main query, making it much slower as a normal custom query with WP_Query. Many people also do not reset the query_posts query with wp_reset_query() when done, which makes query_posts even more evil.

Because we cannot do anything about that, and cannot stop plugins and themes from using query_posts and we can never know if a query_posts query was reset with wp_reset_query(), we need a more reliable copy of the main query object which we know will give us 99.99999% reliable, correct data. That is where $GLOBALS['wp_the_query'] is useful as no WordPress related code can change it's value (except through the filters and actions inside WP_Query itself).

Quick proof, run the following

var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );

query_posts( 's=crap' );


var_dump( $GLOBALS['wp_the_query'] );
var_dump( $GLOBALS['wp_query'] );

and check the results. $GLOBALS['wp_the_query'] did not change, and $GLOBALS['wp_query'] has. So which is more reliable?

Final note, $GLOBALS['wp_the_query'] is NOT a replacement for wp_reset_query(). wp_reset_query() should always be used with query_posts, and query_posts should never be used.

TO CONCLUDE

If you need reliable code which will almost always never fail, use $GLOBALS['wp_the_query'], if you trust and believe plugins and theme code and believe no one uses query_posts or is using it correctly, use $GLOBALS['wp_query'] or $wp_query

IMPORTANT EDIT

Being answering questions on this site now for a couple of years, I saw many users using $wp_query as a local variable, which in turn also breaks the main query object. This further increases the vulnerabilty of the $wp_query.

As example, some people to this

$wp_query = new WP_Query( $args );

which is in essence the exactly the same as what query_posts are doing

6
  • 1
    query_posts() changes global $wp_query. global $wp_the_query holds the reference to the main query Mar 15, 2016 at 19:06
  • My comment wasn't intended as a correction, so my apologies if it did. I was merely summarizing (TL;DR if you will) while pointing out what I believe is one of the most significant aspects of $wp_the_query as it pertains to the WP_Query::is_main_query() method, which was not mentioned :D Mar 16, 2016 at 0:37
  • @EvanMattson Apologies, I misunderstood your first comment ;-). Yes, is_main_query(), which is a wrapper for WP_Query::is_main_query() which checks the current query object against the main query object saved in $GLOBALS['wp_the_query']. This is quite important when you run pre_get_posts actions and just want to target the main query ;-) Mar 16, 2016 at 4:18
  • Pretty well done answer! @EvanMattson That should have been an edit.
    – kaiser
    Apr 6, 2016 at 21:49
  • Can you include mention of is_main_query function in the *IMPORTANT EDIT section? I was using pre_get_posts today and found it utterly useful to use that function since I was looking at $wp_query. Mar 18, 2017 at 0:50
3

The global keyword imports the variable into the local scope, while $GLOBALS just grants you access to the variable.

To elaborate, if you use global $wp_the_query; you can use $wp_the_query inside the local scope without using the word global again. So basically global $wp_the_query can be compared to $wp_the_query = $GLOBALS['wp_the_query']

EDIT

I misread wp_query for wp_the_query so my answer isn't a complete answer to the question but still provides general information about the difference between global $variable and $GLOBALS['variable']

1
  • Please, file an edit as this really is not an answer to the original question. Just FYI $GLOBALS['foo'] allows overriding or unsetting the variable as well. So it's a bit more than what you describe here.
    – kaiser
    Apr 6, 2016 at 21:52
3

Basically one is copy of the other.

0

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.