This has me stumped for a while already. Either I am missing something very obvious or something very not obvious. I am also not entirely sure if this has something to do with WP or purely PHP mechanics at work.

function test() {

    global $wp_query;

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

function test2() {

    global $wp_query;

    query_posts(array('posts_per_page' => 1));
    var_dump($wp_query == $GLOBALS['wp_query']);



boolean true

boolean false

Why does test() evaluates that to true, but test2() evaluates that to false?

2 Answers 2


Update with a better example

header( 'Content-Type: text/plain;charset=utf-8' );
error_reporting( E_ALL | E_STRICT );

function failed_unset()
{   // Copy the variable to the local namespace.
    global $foo;

    // Change the value.
    $foo = 2;

    // Remove the variable.
    unset ( $foo );
function successful_unset()
    // Remove the global variable
    unset ( $GLOBALS['foo'] );

$foo = 1;
print "Original: $foo\n";
print "After failed_unset(): $foo\n";
print "After successful_unset(): $foo\n";


Original: 1
After failed_unset(): 2

Notice: Undefined variable: foo in /srv/www/htdocs/global-unset.php on line 21

Call Stack:
    0.0004     318712   1. {main}() /srv/www/htdocs/global-unset.php:0

After successful_unset():

unset() doesn’t know anything about the global scope in the first function; the variable was just copied to the local namespace.

Old answer

From wp-includes/query.php:

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

Do you see it?

BTW: Someone has made a nice flowchart about this very topic. ;)


query_posts() changes $GLOBALS while all references to the variable $wp_query that you made available per global are not affected by unset. That’s one reason to prefer $GLOBALS (besides readability).

  • Yes, I understand (enough to draw a flowchart) that content of global variable changes. But this doesn't explain why in second function it is different content while accessing essentially same global variable in two different ways?..
    – Rarst
    Apr 2, 2011 at 19:52
  • @Rarst I added a note about the behavior of unset.
    – fuxia
    Apr 2, 2011 at 20:57
  • Still not getting it... The idea is that for same name global variable and member of $GLOBALS array point to the same thing... Or do they not? Per docs unsetting $GLOBALS unsets global variable, so why it isn't either unset or updated to new value assigned?
    – Rarst
    Apr 2, 2011 at 21:07
  • Because the scope of unset is not global. It cannot delete a symbol in your function’s scope. This is not very intuitive and a very common question.
    – fuxia
    Apr 2, 2011 at 21:43
  • Yes, but query_posts() clearly does delete and change the global variable. Then what the heck $wp_query in function continues to point to? It cannot (?) be value in local scope, because there never was such value in local scope.
    – Rarst
    Apr 2, 2011 at 21:47

Have you tried using wp_reset_query(); after your custom query as described at http://codex.wordpress.org/Function_Reference/query_posts ?

  • 2
    My problem is not after custom query, it is inside custom query. Essentially $wp_query, that was declared global in function, no longer point to correct object after that object was unset and re-set by another function. As per comment discussion with toscho under his answer this seems to be some peculiar behavior of PHP rather than WP.
    – Rarst
    Apr 3, 2011 at 15:04

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.