rarst
  • 0
Гуру

Query_posts() в функции приводит к рассинхронизации глобального $wp_query?

  • 0

Это меня уже давно поставило в тупик. Либо я упускаю что-то очень очевидное, либо что-то очень неочевидное. Я также не совсем уверен, имеет ли это какое-то отношение к WP или чисто механике PHP в работе.

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']);
}

test();
test2();

Результат:

логическое значение true

логическое значение false

Почему test() оценивает это как true, но test2() оценивает это как false ?

Share
  1. Обновление с лучшим примером

    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";
    

    Результат

    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() ничего не знает о глобальной области видимости в первой функции; переменная была просто скопирована в локальное пространство имен.


    Старый ответ

    Из wp-includes/query.php :

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

    Вы видите это?

    Кстати: Кто-то сделал хорошую блок -схему по этой самой теме. 😉

    Обновлять

    query_posts() изменяется $GLOBALS, в то время как все ссылки на переменную $wp_query, которые вы сделали доступными global, не затрагиваются unset. Это одна из причин предпочтения $GLOBALS (помимо удобочитаемости).

    • 0
    • Да, я понимаю (достаточно, чтобы нарисовать блок-схему), что содержимое глобальной переменной меняется. Но это не объясняет, почему во второй функции это разное содержимое при доступе к одной и той же глобальной переменной двумя разными способами?..

      • 0
    • @Rarst Я добавил примечание о поведении unset .

      • 0
    • Все еще не понимаю… Идея в том, что глобальная переменная с одним и тем же именем и член $GLOBALS массива указывают на одно и то же… Или это не так? В соответствии с документами $GLOBALS отмена установки отменяет глобальную переменную, так почему же она не сбрасывается и не обновляется до нового назначенного значения?

      • 0
    • Поскольку область действия unset не является глобальной. Он не может удалить символ в области действия вашей функции. Это не очень интуитивный и очень распространенный вопрос.

      • 0
    • Да, но query_posts() явно удаляет и изменяет глобальную переменную. Тогда на что, черт возьми, $wp_query функция продолжает указывать? Он не может (?) быть значением в локальной области видимости, потому что такого значения в локальной области видимости никогда не было.

      • 0
    • Моя проблема не после пользовательского запроса, а внутри пользовательского запроса. По сути $wp_query, то, что было объявлено глобальным в функции, больше не указывает на правильный объект после того, как этот объект был сброшен и повторно установлен другой функцией. Согласно обсуждению комментариев с toscho под его ответом, это похоже на какое-то странное поведение PHP, а не WP.

      • 0
  2. Пробовали ли вы использовать wp_reset_query(); после своего пользовательского запроса, как описано на http://codex.wordpress.org/Function_Reference/query_posts ?

    • 0

Оставить ответ

You must login to add an answer.