質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2126閲覧

WordPress で<?php if (have_posts()) : while (have_posts()) : the_post(); ?>の厳密な処理の違いは?

createwebsite22

総合スコア6

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/12/16 15:38

###≪実現したいこと≫
まず、自作のWordPressで以下のことを実現したいと思い試行錯誤しました。

「サブループにある一連の投稿を任意のカテゴリーにアーカイブ表示させたい」

(例) 【A・B・C】の3つのカテゴリーに分類された、[1~10]の投稿記事を以下のようにサイト上に一覧表示させたい

【A】[記事1] [記事4] [記事6] [記事9] [記事10]
【B】[記事2] [記事3] [記事8]
【C】[記事5] [記事7]

これを実現するために、以下のコードを記述すれば問題なく、私が望んでいることが実現できました。

PHP

1<?php 2$taxonomyがproduct_classの全投稿 = array('taxonomy' => 'product_class'); 3$全カテゴリー = get_categories($taxonomyがproduct_classの全投稿); 4?> 5 6<?php foreach ($全カテゴリー as $各カテゴリー) : ?> 7 8 <h2 class="each-category"> 9 <?php echo $各カテゴリー->name; ?> 10 </h2> 11 12 <ul> 13 14 <?php 15 query_posts( 16 array( 17 'posts_per_page' => '99', 18 'post_type' => 'product', 19 'post_status' => 'publish', 20 'orderby' => 'Date', 21 'order' => 'ASC', 22 'taxonomy' => 'product_class', 23 'term' => $各カテゴリー->slug 24 ) 25 ); ?> 26 27 <?php if (have_posts()) : while (have_posts()) : the_post(); ?> 28 29 <div class="each-post"> 30 <li> 31 カテゴリーに該当する記事 32 </li> 33 </div> 34 35 <?php endwhile; ?> 36 <?php endif; ?> 37 <?php wp_reset_postdata(); ?> 38 </ul> 39 40<?php endforeach; ?>

しかし、一見同じに思えるコードを記述したのですが、うまく反映しないことがありました。
それは<?php if (have_posts()) : while (have_posts()) : the_post(); ?>の部分のコードを少し変えると以下のような違いがありました。

この部分で何がどう裏側で処理されているのか、詳しく教えていただけないでしょうか?


###1.<li>に出力されるはずの投稿記事がまったく反映されない

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
を以下のように記述するとうまく反映されません。

PHP

1<?php if ($have_posts()) : ?> 2<?php while (have_posts()) : the_post(); ?>

一見、同じに見えるのですが、if とwhile をわけて PHPを記述すると**<li> に出力されるはずの投稿記事がまったく反映されません。**
なぜ、同じ <?php ?>の中で記述しいないというだけで出力されないのでしょうか?


###2.一番はじめのカテゴリーの投稿で無限ループになり抜け出せない

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
を以下のように記述するとうまく反映されません。

PHP

1<?php $全投稿 = have_posts(); ?> 2<?php if ($全投稿) : while ($全投稿) : the_post(); ?>

① have_posts(); を変数に代入
② if と while に変数を入れる

これだと、一番初めのカテゴリー今回だと【A】は問題なく取得できます。
しかし、以下のように[記事10]の後が無限ループになってしまいます。

【A】[記事1] [記事4] [記事6] [記事9] [記事10]・・・・・・・・・・・・・・・・・・・・・・・・・

なぜ、<?php endwhile; ?>を記述しているにも関わらず、カテゴリー【A】から抜け出せずに無限ループになってしまうのでしょうか?


###3.$wp_query->have_posts() は問題なく反映させる

代入することがまったくダメなのかと言えばそうではありません。
以下の代入したコーディングだと問題なく反映しました。

PHP

1 <?php 2 $wp_query = new WP_Query( 3 array( 4 'posts_per_page' => '99', 5 'post_type' => 'product', 6 'post_status' => 'publish', 7 'orderby' => 'Date', 8 'order' => 'ASC', 9 'taxonomy' => 'product_class', 10 'term' => $各カテゴリー->slug 11 ) 12 ); ?> 13 14 <?php if ($wp_query->have_posts()) : while ($wp_query->have_posts()) : the_post(); ?>

query_postsの部分を$wp_query = new WP_Queryに代入する。
そして、以下の様にコーディングすると問題なく反映しました。
<?php if ($wp_query->have_posts()) : while ($wp_query->have_posts()) : the_post(); ?>

私からすると、すべて同じ処理がされていると思うのです。
しかし、実際は何がどう違っているのでしょうか?


###「補足情報」

このコードの書き方で毎回エラーが起こるわけではありません。
普通のサブループの場合だとすべて問題なく、各投稿がループして反映されます。

つまり、今回は以下の特別な処理が入っています。
「事前にカテゴリーを抽出し、該当する記事だけを順番にループ」

今回、この壁にぶちあたって、実は違う処理が行われているのではないかと思い質問させていただきました。
詳しい方のアドバイスを頂きたく思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

1 なんか余計なものが付いてますよ

php

1<?php if ($have_posts()) : ?> 23<?php if (have_posts()) : ?>

2
while(have_posts()):
have_posts()の戻り値がfalseになるまで処理を繰り返す、
ということなのに最初のhave_posts()の戻り値をwhileに渡し続けてたら
while(true):してるのと同じなんですから
そりゃ無限ループになりますよね

3
これが正解

query_postsはメインクエリを書き換えるものです
基本的に使わないでください

メインクエリを書き換えたいという場合であっても
query_postsより良い手段があります
その辺りのこともcodexのquery_postsのページに書かれてます

query_posts

メインクエリというのはブラウザからリクエストされたURLに応じた検索条件・検索結果であり、
これを上書きすることはブラウザからのリクエストと検索条件・検索結果を不一致にさせてしまうことであり
どこで何がおかしくなるかわからない地雷を抱えた状態になります

投稿2021/12/16 16:47

KazuhiroHatano

総合スコア7819

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

createwebsite22

2021/12/17 14:59

アドバイス、まことにありがとうございます。 おかげで、疑問だったことが解決できました。 このようなコードはネットに書かれているものをコピペしてすることもあります。 しかし、深く理解していないと、細かなエラーの対処法がわからないですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問