WordPress как на ладони
rgbcode is looking for WordPress developers.

setup_postdata()WP 1.5.0

Устанавливает всевозможные данные поста (кроме глобальной переменной $post).

Заполняет глобальные переменные, которые нужны для корректной работы некоторых Тегов Шаблона, которые используются внутри Цикла WordPress. Некоторые из таких тегов шаблона: the_author(), wp_link_pages(), the_weekday_date(), is_new_day().

Устанавливает следующие глобальные переменные:

$id
$authordata
$currentday
$currentmonth
$page
$pages
$multipage
$more
$numpages

Функция не устанавливает переменную $post как глобальную. Поэтому вам нужно сделать это самостоятельно.

Функция ожидает, что передаваемая переменная имеет тот же объект что и глобальная переменная $post. Т.е. передаваемая переменная должна быть глобальным объектом $post. Если функция используется внутри цикла, то нужно передать текущий объект поста в цикле.

Всегда, когда используется эта функция, после цикла нужно сбрасывать глобальную переменную $post с помощью wp_reset_postdata().

Смотрите функцию the_post() - она работает на основе этой функции.

Работает на основе: WP_Query::setup_postdata()
Основа для: the_post()
1 раз — 0.000149 сек (быстро) | 50000 раз — 5.16 сек (быстро)

Хуков нет.

Возвращает

true|false. Почти всегда возвращает true. Вернет false, когда глобальная переменная $wp_query не установлена или не является объектом WP_Query.

Использование

global $post;
setup_postdata( $post );
$post(объект/число) (обязательный)
Объект или ID текущего поста.

Примеры

2

#1 Еще пример объясняющий работу setup_postdata()

Этот пример взят из комментария пользователя:

Вопрос:

Приветствую! Кажется я что то не допонимаю:

1) Такой код:

$top_posts = get_posts([
	'posts_per_page' => 5,
]);

if ( $top_posts ) {
	foreach ( $top_posts as $post ) {
		// setup_postdata($post);
		the_title();
		echo '<hr>';
	}
}
wp_reset_postdata();

Работает нормально, выводит то что нужно. Зачем тогда использовать setup_postdata($post); ?

2) Такой код:

$top_posts = get_posts([
	'posts_per_page' => 5,
]);

if ( $top_posts ) {
	foreach ($top_posts as $item) {
		setup_postdata($item);
		the_title();
		echo '<hr>';
	}
}
wp_reset_postdata();

Выводит 5 раз заголовок первой записи. Вот тут вообще не понял, почему? Разве обязательным является имя переменной $post при переборе цикла?

Ответ:

1 код

В описании setup_postdata(), написано зачем она нужна:

Заполняет глобальные переменные: $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages. Они нужны для корректной работы Тегов Шаблона, которые должны использоваться внутри Цикла WordPress.

Т.е. без нее некоторые теги шаблона будут работать некорректно! Для конкретно the_title() она не нужна...

2 код

the_title() и подобные ей работают именно с $post, указывая $post для foreach ты как бы изменяешь значение глобальной $post на текущее, а если указываешь $item, то переопределения не происходит, поэтому 5 одинаковых заголовков...

setup_postdata() в этом вопросе не фигурирует, у него другая задача - определить другие глоб.переменные кроме $post нужные для тегов шаблона. Например можно написать так:

...
	foreach ($top_posts as $item) {
		$post = $item; // перепишем глоб. `$post`
		setup_postdata($item);
		the_title();
		echo '<hr>';
	}
...

И из этого кода видно, что проще сразу $post использовать...

Кроме того, у тебя в коде нет определения $post как глобальной, а это значит что твой код находится в каком-то файле напрямую (т.е. он в глобальной области видимости PHP) и поэтому там $post уже глобальная. Так например, если обернуть твой код в функцию, то в начале функции нужно будет написать global $post, чтобы $post была глобальной, когда используется внутри функции (в локальной области видимости кода). Иначе теги шаблона типа the_title() правильно работать не будут.

1

#2 Как правильно передавать аргумент $post

Допустим мы получаем данные поста в переменную $post_object, тогда нам нужно создать переменную с названием $post и передать в нее эти данные. setup_postdata() работает именно с глобальной переменной $post.

global $post;
setup_postdata( $post );

// или

// Изменим глоб. $post - это нужно обязательно, но это не входит
// в задачи функции setup_postdata()
$post = $post_object;
setup_postdata( $post_object );

// Используем Теги Шаблона
// the_title();

// в конце всех операций обязательно возвращаем $post в исходную
wp_reset_postdata();

Короткая запись примера выше:

setup_postdata( $GLOBALS['post'] = $post_object );

А вот так неправильно:

global $post;

setup_postdata( $post_object );
1

#3 Если в аргумент функции передать не $post

Демонстрация того, что получится, если в качестве аргумента передать не глобальную переменную $post, а любую другую - функция не будет работать как нужно:

global $post;

// Неправильно!
$posts = get_posts("posts_per_page=2");
foreach( $posts as $pst ){
	setup_postdata( $pst );
	echo the_title();
	echo '<br>';
}
echo '$post->post_title - '. $post->post_title . '<br>';

wp_reset_postdata();

/*
Вернет:
Заголовок текущей страницы
Заголовок текущей страницы
$post->post_title - Заголовок текущей страницы
*/

// Правильно!
// повторяем только определим $post
$posts = get_posts("posts_per_page=2");
foreach( $posts as $pst ){
	$post = $pst;
	setup_postdata( $pst );
	echo the_title();
	echo '<br>';
}
echo '$post->post_title - '. $post->post_title . '<br>';
wp_reset_postdata();

/*
Вернет:
Заголовок полученного поста
Заголовок второго полученного поста
$post->post_title - Заголовок второго полученного поста
*/

// Правильно!
// повторяем только с $post вместо $pst
$posts = get_posts("posts_per_page=2");
foreach( $posts as $post ){
	setup_postdata( $post );
	echo the_title();
	echo '<br>';
}
echo '$post->post_title - '. $post->post_title . '<br>';
wp_reset_postdata();

/*
Вернет тоже что и код до этого:
Заголовок полученного поста
Заголовок второго полученного поста
$post->post_title - Заголовок второго полученного поста
*/
0

#4 Пример с циклом get_posts()

Получим посты из категории 1 и выведем их в виде ссылок:

<ul>
	<?php
	global $post;
	$args = array( 'numberposts' => 5, 'offset'=> 1, 'category' => 1 );
	$myposts = get_posts( $args );
	foreach( $myposts as $post ){
		setup_postdata($post);
		?>
		<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
		<?php
	}
	wp_reset_postdata();
	?>
</ul>
0

#5 Получим посты прямым запросом из базы данных

<ul>
	<?php
	global $wpdb, $post;
	$result = $wpdb->get_results(
		"SELECT * FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'"
	);
	foreach($result as $post){
		setup_postdata($post);
		?>
		<li><a href="<?php the_permalink()?>"><?php the_title();?></a></li>
		<?php
	}
	wp_reset_postdata();
	?>
</ul>

Заметки

  • Global. WP_Query. $wp_query WordPress Query object.

Список изменений

С версии 1.5.0 Введена.
С версии 4.4.0 Added the ability to pass a post ID to $post.

Код setup_postdata() WP 6.4.3

function setup_postdata( $post ) {
	global $wp_query;

	if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
		return $wp_query->setup_postdata( $post );
	}

	return false;
}
2 комментария
    Войти