結論
WordPressのテンプレートでは$posts
はメインループの記事リストを指すため、利用すべきではない。
何があったか
<?php
$args = array(
'post_type' => 'post', `
);
$posts = get_posts($args);
foreach ($posts as $post) :
// (以下省略)
?>
このように記述したところ、メインループの記事がget_posts()
で取得した記事に置き換わりました。
get_posts()はメインループに影響を与えないはずなので、この挙動に最初混乱しました。
原因は受け取る$posts
という変数で、メインループで表示される記事リストを格納しているようです。
結果としてget_posts()
で受け取った内容でメインループの記事リストを上書きしていました。
$found_posts = get_posts($args);
のように別の変数名で受け取るべきのようです。
考察
wp-includes/class-wp.php
の中を覗いたところ
public function register_globals() {
global $wp_query;
// Extract updated query vars back into global namespace.
foreach ( (array) $wp_query->query_vars as $key => $value ) {
$GLOBALS[ $key ] = $value;
}
$GLOBALS['query_string'] = $this->query_string;
$GLOBALS['posts'] = & $wp_query->posts;
$GLOBALS['post'] = isset( $wp_query->post ) ? $wp_query->post : null;
$GLOBALS['request'] = $wp_query->request;
if ( $wp_query->is_single() || $wp_query->is_page() ) {
$GLOBALS['more'] = 1;
$GLOBALS['single'] = 1;
}
if ( $wp_query->is_author() && isset( $wp_query->post ) ) {
$GLOBALS['authordata'] = get_userdata( $wp_query->post->post_author );
}
}
とありました。$wp_query
はメインクエリを保持するグローバル変数です。
$posts
は$wp_query->posts
の参照渡しのようですね。