WordPressのループで使われるhave_posts・$postの役割と$wp_query

have_postsとthe_postの役割とは

ループ処理でおなじみのhave_postsとthe_postですが、いったいどんな働きをしているのでしょうか?
今回は少し掘り下げて調べてみました。

have_posts()関数で行われる処理

関数とは「どこかから値または配列を持ってきて何かしらの処理をする」ものなので、もちろんhave_postsも何かしらの配列を処理した上で条件を確定しています。
まずはリファレンスを見てみます。

この関数は現在の WordPress クエリにループできる結果があるかどうかをチェックします。ブール型関数で、TRUE または FALSE を返します。
WordPressCodex日本語版

ループしたくてもループするデータがなければ実行できないので、データを持っているかの確認ということですね。
言葉通り、記事データ(posts)を持っているか(have)の確認をしています。

投稿記事を表示する基本的なループ構文

<?php
	if( have_posts() ) :
		while( have_posts() ): the_post();
			the_content();
		endwhile;
	endif;
?>

教科書的な見る基本的な構文。この中にhave_postが2回出てきますね。
if構文のほうは記事データがあるか確認した後に次の処理を実行する、while構文内のほうは都度記事データを一つずつ抜き取って、残りがあるかどうかの確認をしています。

whileループ構文についてはこちらにまとめてありますので宜しければご覧ください。

the_post()の役割

リファレンスにはこう書かれています。

ループを次の投稿へ進めます。 次の投稿を取得して、それを「現在の投稿」としてセットアップし、ループの’in the loop’プロパティを true にします。
WordPressCodex日本語版

the_post()の作用は2つあります。

1.whileループで次の処理に進める。
2.ループ内で使う投稿データを用意する。

1はリファレンスの説明にある通りループのスイッチを入れる役割ですね。
2はループ内で使用できる$postという変数が用意されていてます。

$postは投稿1つ分のデータの入れ物

$postは投稿1つ分のに切り分けたデータの入った変数になります。
ループ内で表示したいデータを抽出するには投稿1つだけの状態の方が都合が良いので、データを小分けにして代入する役割がthe_post()で、その代入先が$postということなります。

そもそもどこから投稿データを持ってきているのか

さて前述した通り関数はどこからか値を持ってこないと処理ができないのですが、そもそもどこから持ってきているのでしょうか?

それは$wp_queryというグローバル変数です。

グローバル変数とは

システム内であらかじめ設定されている変数。システムを機能させる上で必要なものや便利なものが格納されています。
なのでこの変数名を使うことはもちろん、書き換えも厳禁です。
ちなみに前述した$postもグローバル変数になります。

$wp_queryには記事ID・タイトル・コンテンツなど様々なデータが格納されていて、ここから抽出することでブログなどの表示を可能にしている大事な変数です。
さらに表示するテンプレートによって必要なデータを可変的に格納するという機能がポイントです。

$wp_queryのおかげでページに合わせた表示がカンタンにできる

例えばsingle.phpでこの関数を参照した際は該当する記事の内容のみが格納され、archive.phpの場合はカテゴリー・タブ等該当する範囲の記事が格納される、といった具合です。

ですので前述したwhileループの基本構造をそれぞれのテンプレートに書くと、表示結果も変わります。
使う側としてはどんなテンプレートに対しても同じ構文を使っておけば適宜希望する結果が表示されるという利便性が実現されていますが、運用する上で気を付ける点でもあります。
例えばページネーションを実装する場合、投稿ページと固定ページでは$wp_queryにあらかじめ格納されているパラメータが違うため同じコードを書いても機能しません。

このコードでこの値が取得できるはずなのに…といったトラブルがあった時はテンプレートタイプを疑うことが解決の近道になる場合もあります。

まとめ

ということで簡単にですがWordPressループでよく出てくるhave_posts()から、一番大事だと言っても過言ではない$wp_queryの解説をしていきました。

下記のコードで$wp_queryのデータが見られますので、参考に見ておくと理解が進むと思います。
前述した通り、書き込むテンプレートによって表示されるデータが違うことは注意しておいてください。

<pre><?php print_r($wp_query); ?></pre>

ちなみにhave_posts()の他にデータの有無を確認する分岐条件の関数はいくつかあるのですが、タグの有無を確認するhas_tag()など、「have」と「has」が付くものがあります。
何が違うんだろうといくらか調べてみましたが、単に英語の複数形と単数形とで動詞が変化しているだけの様です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA