query_posts() in function makes global $wp_query out of sync?

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";
failed_unset();
print "After failed_unset(): $foo\n";
successful_unset();
print "After successful_unset(): $foo\n";

Result

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) {
    unset($GLOBALS['wp_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. 😉

Update

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).

Leave a Comment