WordPress как на ладони
Мощный и не дорогой хостинг от Fornex.com Хостинг, VPS/VDS и отдельные сервера только на SSD дисках. 7 дней бесплатного тестирования.

setup_postdata() WP 1.5

Устанавливает глобальные данные поста. Нужен для удобного использования Тегов шаблона связанных с оформление поста: the_title(), the_permalink() и т.д.

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

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

Функция работает именно с глобальной переменной $post или с её копией, но лучше не экспериментировать и просто всегда использовать переменную $post она в ВП центровая при работе с записями.

С WP 4.4 появилась возможность передать ID поста (число) в переменную $post.

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

Работает на основе: WP_Query::setup_postdata()
✈ 1 раз = 0.000149с = быстро | 50000 раз = 5.16с = быстро

Хуков нет.

Возвращает

Всегда возвращает true.

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

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

Примеры

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

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

global $post;

// Перенаправим полученные данные поста в переменную $post и не в какую другую.
$post = $post_object;

setup_postdata( $post );
// the_title();

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

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

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

global $post;

setup_postdata( $post_object ); // опс

#2 Пример с циклом 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>

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

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

#4 Если в аргумент функции передать не $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>';

/*
Вернет:
Заголовок текущей страницы
Заголовок текущей страницы
$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>';
/*
Вернет:
Заголовок полученного поста
Заголовок второго полученного поста
$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>';

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

#5 Еще пример объясняющий работу 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() правильно работать не будут.

Код setup_postdata: wp-includes/query.php VER 5.0.1

<?php
function setup_postdata( $post ) {
	global $wp_query;

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

	return false;
}

Cвязанные функции

Из метки: loop (Цикл WP)

Еще из метки: query (запрос)

Еще из раздела: Запросы

Еще из тегов шаблона: Основные

1 коммент
Здравствуйте, !     Войти . Зарегистрироваться