$post->ID не работает

23 авг. 2012 г., 18:07:09
Просмотры: 33.8K
Голосов: 4

У меня есть следующий код, и хотя get_the_ID() работает, $post->ID не работает, почему?

    $the_query = new WP_Query( array(
        'post_type' => 'custompost',
    ) );

    while ( $the_query->have_posts() ) : $the_query->the_post();
        echo $post->ID;
    endwhile;

Чтобы использовать $post->ID, вам нужно объявить переменную $post как глобальную внутри цикла:

    $the_query = new WP_Query( array(
        'post_type' => 'custompost',
    ) );

    while ( $the_query->have_posts() ) : $the_query->the_post();
        global $post;
        echo $post->ID;
    endwhile;

Альтернативно, вы можете использовать функцию get_the_ID(), которая является рекомендуемым способом получения ID поста в WordPress.

0
Все ответы на вопрос 2
5

Ваш цикл WP_Query неполный. Вы не проверяете, были ли найдены записи перед началом цикла, не выводите сообщение об их отсутствии и не очищаете данные после завершения. Кроме того, вы используете альтернативный синтаксис, который нарушает сопоставление скобок в IDE, усложняя себе жизнь.

Попробуйте добавить global $post; следующим образом:

global $post;
$the_query = new WP_Query( array(
    'post_type' => 'custompost'
) );

if($the_query->have_posts()){
    while ( $the_query->have_posts() ) {
        $the_query->the_post();
        echo $post->ID;
    }
    wp_reset_postdata();
}else {
    echo 'записи не найдены';
}

При написании запросов важно быть последовательным и делать всё правильно. Поэтому я рекомендую ознакомиться с этими слайдами Эндрю Нацина, разработчика ядра WordPress в Automattic:

http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012

Они расскажут, где уместно использовать каждый тип запроса, как их правильно применять и почему.

В приведённом выше коде я добавил условие if для проверки наличия записей и функцию wp_reset_postdata, которая позволяет продолжить использование основного запроса, очищая данные после пользовательского цикла.

23 авг. 2012 г. 18:17:29
Комментарии

Спасибо, глобальная переменная сработала. Как это работает? И что именно делает wp_reset_postdata()? Она всегда нужна?

urok93 urok93
23 авг. 2012 г. 18:22:14

Полагаю, $post просто была вне области видимости. Что касается wp_reset_postdata() - когда вы запускаете цикл, переменная $post изменяется, поэтому wp_reset_postdata() работает как отмена этих изменений, позволяя использовать несколько циклов внутри основного запроса без его нарушения.

Tom J Nowell Tom J Nowell
23 авг. 2012 г. 18:35:42

Вам стоит посмотреть эти слайды: http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012 Это невероятно полезная презентация по созданию запросов от Nacin, одного из основных разработчиков ядра WordPress, там всё объясняется

Tom J Nowell Tom J Nowell
23 авг. 2012 г. 18:36:37

Я согласен со всем, кроме комментария о синтаксисе "other". В большинстве случаев мы будем выводить HTML внутри цикла while, поэтому синтаксис "other" обычно более подходящий. Ссылка на документацию по альтернативному синтаксису на случай, если кому-то интересно - http://php.net/manual/en/control-structures.alternative-syntax.php

John_911 John_911
4 мар. 2017 г. 08:16:43

Если вы не согласны, я предлагаю вам написать пост в блоге или задать новый вопрос, но вам понадобится что-то более весомое, чем просто утверждение, что это "более подходяще" — заявления должны быть подкреплены доказательствами

Tom J Nowell Tom J Nowell
6 мар. 2017 г. 01:02:56
0

Как выяснил Том Новелл, решение заключается в добавлении ссылки на global $post.

Когда вы выполняете the_query->the_post(), WordPress загружает первый результат запроса в глобальный объект $post. Именно так он настраивает всё для стандартных тегов шаблонов:

  • the_title()
  • the_content()
  • the_excerpt()
  • и т.д.

Обратите внимание, что мы не передаём никакие параметры в эти функции. Мы просто их вызываем. Каждая из этих функций внутри себя обращается к глобальному объекту $post, чтобы обработать, подготовить и вывести нужные данные.

Внутри вашего цикла вы спокойно вызываете the_post(), чтобы заполнить данные, но у вас нет ссылки на сами данные в области видимости вашего цикла. Если вы хотите избежать обращения к глобальному объекту $post, вы можете использовать get_the_ID().

Как и другие теги шаблонов, упомянутые выше, get_the_ID() получает данные из глобального объекта $post внутри себя, так что вам не нужно делать это вручную.

Но если вы хотите сделать это самостоятельно, просто добавьте глобальную ссылку перед использованием $post:

$the_query = new WP_Query( array(
    'post_type' => 'custompost',
) );

while ( $the_query->have_posts() ) : $the_query->the_post();
    global $post;  // Добавьте эту строку, и всё заработает
    echo $post->ID;
endwhile;

Что такое wp_reset_postdata()?

Если вы создаёте несколько циклов (например, у вас есть основной цикл записей, но внутри него вызывается дополнительный цикл), вы можете использовать wp_reset_postdata(), чтобы сбросить настройки.

По сути, the_post() устанавливает глобальный объект $post так, чтобы он содержал данные из запроса. the_query->the_post() перезаписывает $post данными из the_query. wp_reset_postdata() возвращает $post к исходному запросу.

Таким образом, если вы используете вложенные или множественные циклы, wp_reset_postdata() позволяет вернуться к циклу и объекту $post, которые были доступны до вызова дополнительного the_query->the_post().

23 авг. 2012 г. 18:53:44