WordPressで投稿記事を3パターン表示したい

このQ&Aのポイント
  • WordPressで投稿記事を3パターン表示するための方法について相談です。
  • 投稿記事を3ファイルに分けて表示したいが、うまくいかず全てpage.phpとして表示されます。アドバイスをお願いします。
  • page.php、page-secound.php、page-third.phpの3つのファイルがあり、それぞれのページに割り当てたカスタムフィールドを使って振り分けたいです。
回答を見る
  • ベストアンサー

wordpressで投稿記事を3パターン表示したい

投稿記事を3ファイルに分けて表示したいのですが、うまくいかず全てpage.phpとして表示されます。振り分けることができないのですが、アドバイスよろしくお願いします。 前提として page.php page-secound.php page-third.phpの3ファイルがあり固定ページのテンプレートにしている。 <?php /* Template Name: 画像2タイトル1 Template Post Type: page */ ?> <?php /* Template Name: 画像3タイトル1 Template Post Type: page */ ?> 以下のカスタムフィールド名を各記事に割り振っております。 single_rss_feed1 duuble_rss_feed 2 triple_rss_feed 3 ※1つ目の方法 <!--index.phpの文頭に書くコード--!> <?php if(get_post_meta($post->ID,'single_rss_feed1',true) == 'A'): ?> <?php include(('main-first.php') == 'A'); ?> <?php elseif (get_post_meta($post->ID,'duuble_rss_feed2',true) == 'B'): ?> <?php include(('page-secound.php') == 'B'); ?> <?php elseif (get_post_meta($post->ID,'triple_rss_feed3',true) == 'C'): ?> <?php include(('page-third.php') == 'C'); ?> <?php else: ?> <?php endif; ?> _______________________________ ※2つ目の方法 <!--functions.phpに書くコード--!> function custom_template_include($template) { global $post; if (!is_page()) return $template; if (get_post_meta($post->ID, ' duuble_rss_feed 2')) $new_templete = locate_template(array('sub-secound.php')); if (get_post_meta($post->ID, ' triple_rss_feed 3')) $new_template = locate_template( array( 'sub-third.php' )); if (!empty($new_template)) return $new_template; return $new_template; }

  • PHP
  • 回答数30
  • ありがとう数44

質問者が選んだベストアンサー

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.30

front-page.phpのコードをもとにして、search.phpを作ってみました。 コードはこちらです。 https://wandbox.org/permlink/vqm36EiTCbCl1QKF 私のfront-page.phpが古いかも知れませんが、変更箇所がわかるようにしていますので、最新のものと見比べてみてください。 削除している箇所は以下のように括ってコメント化しています。 /* ここから削除 (もとのコード) ここまで削除 */ 追加している箇所は以下のように括っています。 /* ここから追加 */ (追加したコード) /* ここまで追加 */ 削除と追加はそれぞれ二か所ずつあります。 SQL文は大幅に変更しています。 1.'single_rss_feed1'は以前やられていたように直接JOINしました。 2.画像はWordPress関数で取得するのでなくしました。 3.カテゴリーはWordPress関数で取得するのでなくしました。 4.$post_itemsとして使えるよう取得項目はwp_postsのすべての項目にしました。 5.全件件数取得のためのSQL文を別途追加しました。

php_learn
質問者

お礼

コードの修正ありがとうございます。 どうしても腑に落ちなかったため先に質問だけをしてしまいました。すみません。 あと2日で質問の期限が切れてしまうので、続きはこちらにお願いいたします。 https://okwave.jp/qa/q10006002.html

php_learn
質問者

補足

2.画像はWordPress関数で取得するのでなくしました。 3.カテゴリーはWordPress関数で取得するのでなくしました。 4.$post_itemsとして使えるよう取得項目はwp_postsのすべての項目にしました。 A.それぞれSQLで取得しなければいけない項目だと思っていたのですが、postから取得できるのでしょうか? 今回の場合、検索データを使うためにはSQLを通す必要がある。データベースから情報をもらい、そこを通して各項目を表示する、postの場合現在のデータを表示するものだと思っていて、自分の中では$resultを通さないと条件の指定はできないと考えております。 function set_other_data($post)にSresultは通す必要はないのでしょうか? SQLを使い表示する場合は条件もSQLの関数を使うものだと思っておりました。

その他の回答 (29)

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.19

回答No.18のつづき。 新しいSQL文の重複回避はGROUP BYによってできています。 (1)と同じようにcomment_post_IDだけを取得してみます。 ----(4) SELECT comment_post_ID FROM wp_comments GROUP BY comment_post_ID ---- 結果は(1)と同じだと思います。 件数は同じですが、順番まで同じかどうかは今は考えないでおきます。 どちらにしても重複していないことが確認できます。 これがcomment_post_IDをグループキーとしてグループ化したことになります。 グループ化するとグループキーが同じものをひとつにするので重複しなくなります。 ですが重複させないためのものではありません。 次に(2)と同じ項目で取得してみます。 ----(5) SELECT comment_post_ID, comment_date, comment_content FROM wp_comments GROUP BY comment_post_ID ---- 結果は(2)とは違うと思います。 違うどころか、重複もしていません。 ですが「重複しなくなった、ラッキー」と言うわけではありません。 なぜなら取得されなくなったデータがあるからです。 comment_post_IDが重複しなくなったのはいいのですが、comment_dateやcomment_contentはいったいどのデータのものなのか。 (2)では重複していたcomment_post_IDには、それぞれ別々のcomment_dateやcomment_contentがあったはずです。 なのにその中のどれかのデータだけが取得されていますが、他のデータは取得されていません。 取得されたデータをそのまま使って大丈夫なのか、それが取得したかったデータなのか、と言う疑念が残ります。 (3)と同じ項目にしても同様です。 ----(6) SELECT comment_post_ID, comment_content FROM wp_comments GROUP BY comment_post_ID ---- 取得されたcomment_contentはいったいどのデータのものなのかわかりません。 どのデータのものでもよければ、このようなSQL文が書けるのはMySQLの楽できるところですが、今は関係ないので説明はやめておきます。 ではでたらめなデータを取得してくるGROUP BYとはなんのためにあるのか。 その前に。 以前、他のデータベースではグループ関数を使っている項目以外の取得項目すべてをGROUP BYに書く必要があると説明しました。 (6)ですべての項目を書いてみます。 ここにはグループ関数はないので気にしないでください。 ---- SELECT comment_post_ID, comment_content FROM wp_comments GROUP BY comment_post_ID, comment_content ---- (3)と同じ結果になったと思います。 まったく同じコメント文にしていただいたものは重複していませんし、出てこなくなったcomment_contentもありません。 これで取得するものと方法は安定したことになります。 それではGROUP BYの本来の使い方を説明しておきます。 例えば以下のようなSQL文です。 ---- SELECT comment_post_ID, MAX(comment_date) AS max_comment_date, COUNT(*) AS comment_count FROM wp_comments GROUP BY comment_post_ID ---- これで取得できるのは、comment_post_IDごとの、comment_dateの最大値(新しい日付)と、件数です。 MAX()とCOUNT()はグループ関数と呼ばれるもので、GROUP_CONCAT()の仲間です。 他には最小値を求めるMIN()や、合計値を求めるSUM()などがあります。 コメントには合計値を求めるような項目はないので想像しにくいかもしれませんね。 このようにグループキーが同じものを集めて何かするためのものがGROUP BYで、何をするかがグループ関数です。 試しに、GROUP_CONCAT()も使ってみます。 ---- SELECT comment_post_ID, MAX(comment_date) AS max_comment_date, COUNT(*) AS comment_count, GROUP_CONCAT(comment_content) AS comment_contents FROM wp_comments GROUP BY comment_post_ID ---- コメント文が連結されて取得されると思います。 ただコメント文がまったく同じものは重複して連結されているものがあると思います。 そこで同じものは不要だという場合は、GROUP_CONCAT()にDISTINCTを書きます。 ---- SELECT comment_post_ID, MAX(comment_date) AS max_comment_date, COUNT(*) AS comment_count, GROUP_CONCAT(DISTINCT comment_content) AS comment_contents FROM wp_comments GROUP BY comment_post_ID ---- このように重複をなくすためのDISTINCTと、グループ化するためのGROUP BYとで、似たようなところもありますが、それぞれ別々のためのものです。 新しいSQL文では投稿記事のIDでグループ化しているので、重複はしていませんがそのためではなく、グループ関数を使うためにグループ化したと言うわけです。

php_learn
質問者

お礼

すみません下記の内容を表示したかったのですが、取り出して表示する際は全く別の書き方になるのでしょうか? 表示はechoで行うのは参考サイトからわかるのですが、取得の際のfunctionsの書き方がよくわかりません… $categories = [];は$postを使用していないため継続して使えると考えています。 <li></li>の中に取得項目をpage-front.phpのように書く予定です。 //<li></li>の中に日付け、カテゴリー、コメント数、抜粋、続きを読むを出力する予定です。 <?php if ($results) : ?> <ul> <?php foreach ($results as $result) : ?> <li> </li> <?php endforeach; ?> </ul> //書き方がよくわからない function set_other_data($post){ } //そのまま <?php $categories = []; foreach (get_categories() as $category) { $categories[$category->cat_ID] = $category; } ?> ______________________________________________________________ function set_other_data($post) { // アイキャッチIDを取得 $post_thumbnail_id = get_post_thumbnail_id($post); // アイキャッチ画像の確認 if ($post_thumbnail_id) { // 存在する $image_src = wp_get_attachment_image_src($post_thumbnail_id); // サムネイルの画像URLを設定 $post->thumbnail = $image_src[0]; } else { // 存在しない $post->thumbnail = 'noimage.jpg'; } // カテゴリーIDを取得 $post->categories = wp_get_post_categories($post->ID); // コメントテキスト if (0 == $post->comment_count) { // コメントなし $post->comments = __('No Comments'); } else { // コメントあり $post->comments = $post->comment_count.'件のコメント'; } // コメントリンク $post->comments_link = get_comments_link($post->ID); } ※今後$postを作り替えるコード ________________________ $group_per_block = 5; //ブロックあたり投稿グループ件数 //投稿読み込み $posts_per_block = $wp_query->post_count / $block_per_page;//元々設定したコードを追加 $posts_per_page = $block_per_page * $group_per_block; //ページあたり投稿件数 5×2の10件画像は1なので$posts_per_group省略 $posts_offset = ($current_page - 1) * $posts_per_page; //投稿オフセット $args = [ 'posts_per_page' => $posts_per_page, 'offset' => $posts_offset, 'meta_key' => 'single_rss_feed 1',/*カスタムフィールドのフィールド名*/ ]; $post_items = get_posts($args); //ページリンク $display_pages = 5; //番号を表示したいページ数 $display_page_count = 0; $pages = ceil($wp_query->found_posts / $posts_per_page); for ($i = 1; $i <= $pages; ++$i) { if (1 == $i) { $page_text = '<<'; echo "<a href=\"?page={$i}\">{$page_text}</a> "; if ($current_page > 1) { $j = $current_page - 1; } else { $j = 1; } $page_text = '<'; echo "<a href=\"?page={$j}\">{$page_text}</a> "; } if ($i >= $current_page && ++$display_page_count <= $display_pages) { $page_text = $i; echo "<a href=\"?page={$i}\">{$page_text}</a> "; } if ($i == $pages) { if ($current_page < $pages) { $j = $current_page + 1; } else { $j = $pages; } $page_text = '>'; echo "<a href=\"?page={$j}\">{$page_text}</a> "; $page_text = '>>'; echo "<a href=\"?page={$i}\">{$page_text}</a> "; } }

php_learn
質問者

補足

下記の3パターンを覚えておきます。解説いただきありがとうございます。 1.グループキーが同じものは重複しない GROUP BY comment_post_ID 2.他のデータベースではグループ関数を使っている項目以外の取得項目すべてをGROUP BYに書く必要がある SELECT comment_post_ID, comment_content FROM wp_comments GROUP BY comment_post_ID, comment_content 3.comment_post_ID,●AS●,GROUP_CONCAT(DISTINCT)AS● SELECT comment_post_ID, MAX(comment_date) AS max_comment_date, COUNT(*) AS comment_count, GROUP_CONCAT(comment_content) AS comment_contents FROM wp_comments GROUP BY comment_post_ID comment_dateやcomment_contentはいったいどのデータのものなのか。 A.GROUP BYは連結するものだからですね。

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.18

・以前はすべての項目に対し、$result->post_idを渡すことで記事重複表示を避けていたのですが、こちらは$SQLで対策をしている場合必要ないのでしょうか? ID重複を避けていたのは$result->post_idを渡すことでではありません。 ---- SELECT DISTINCT post_id ---- ここに書いてあるDISTINCTが重複させないための記述です。 実はこれもSQLで重複しないようにされていたのです。 SQLの勉強の教材がWordPressなのはちょっぴり枷になっています。 教える方も教わる方も。 普通はサンプルデータとSQL文で簡単に学べるものなのですが、いきなりWordPressで勉強するのは上級者より上な感じがしています。 ぼやいても仕方がないので、手ごろなテーブルで説明してみます。 ただし勉強のためのものなので、WordPressで使うためのものではありません。 コメントのテーブルがよさそうなので、これでデータを用意しましょう。 ふたつの投稿記事に、それぞれふたつコメントを登録してください。 ひとつの投稿記事のコメントはコメント文をまったく同じにしていただき、もうひとつの投稿記事のコメントはコメント文をまったく違うものにしてください。 まずはコメントの全データを確認してみます。 ---- SELECT * FROM wp_comments ---- するとcomment_post_IDが同じものがいくつか表示されると思います。 comment_post_IDはそのコメントがどの投稿記事のものかを示すものです。 ひとつの投稿記事に複数のコメントがあればその分同じcomment_post_IDが重複して表示されています。 次はそれだけを取得してみます。 ---- SELECT comment_post_ID FROM wp_comments ---- この項目だけになりましたが、重複したままです。 次にDISTINCTを使って重複しないようにしてみます。 ----(1) SELECT DISTINCT comment_post_ID FROM wp_comments ---- これで重複しなくなったと思います。 DISTINCTの使い方としての説明はこれだけですが、新しいSQL文で重複しなくなったのとは違う方法です。 DISTINCTが何をしているのか知っていただきたいので、しばらくおつきあいください。 DISTINCTを付けて項目を増やしてみます。 ----(2) SELECT DISTINCT comment_post_ID, comment_date, comment_content FROM wp_comments ---- DISTINCTがあるのに重複していると思います。 次はcomment_dateをなくしてみます。 ----(3) SELECT DISTINCT comment_post_ID, comment_content FROM wp_comments ---- 先ほどと違って、ちょっとだけ重複がなくなったと思います。 まったく同じコメント文にしていただいたものは重複していません。 どういうことかというと、DISTINCTは取得項目の値がすべて同じものは一行にする、と言うものです。 (2)comment_dateがある方は、comment_post_IDとcomment_contentが同じでもcomment_dateが違うためにcomment_post_IDが重複して別々の行になっています。 (3)comment_dateがない方は、comment_post_IDとcomment_contentが同じであればその分が一行になるので、コメント文が同じcomment_post_IDは重複しないですが、コメント文が違うcomment_post_IDは重複しています。 (1)comment_post_IDだけのものはcomment_post_IDが同じであればその分が一行になるので、項目がひとつの場合は重複するものはひとつもないようになります。

php_learn
質問者

お礼

https://oku-log.com/blog/post-thumbnails/ 上記の参考サイトからなんとなく書き方は分かったのですが$resultをechoの際に通す必要はないのでしょうか? 画像分岐のコードは下記でいいのでしょうか? SQLを使っていて、global $wpdb;でデータを出力するのであれば、SQLの記述が必要なくなってしまうのですが、分岐の際はどのように書けばいいのでしょうか? アドバイスよろしくお願いいたします。 ※該当箇所 <?php echo get_the_post_thumbnail( $post->ID, 'rect', array( 'class' => 'archive-thumbnail' ) ); ?> ※画像分岐のコード //アイキャッチを有効化 add_theme_support( 'post-thumbnails' ); //画像サイズ追加 add_image_size('rect', 640, 400, true); //画像URLからIDを取得 function get_attachment_id_by_url( $url ) { global $wpdb; $sql = "SELECT ID FROM {$wpdb->posts} WHERE post_name = %s"; preg_match( '/([^\/]+?)(-e\d+)?(-\d+x\d+)?(\.\w+)?$/', $url, $matches ); $post_name = $matches[1]; return ( int )$wpdb->get_var( $wpdb->prepare( $sql, $post_name ) ); } //画像をサムネイルで出力 function catch_that_image() { global $post; $first_img = ''; $output = preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches ); $first_img_src = $matches[1][0]; $attachment_id = get_attachment_id_by_url( $first_img_src ); $first_img = wp_get_attachment_image( $attachment_id, 'rect', false, array( 'class' => 'archive-thumbnail' ) ); if( empty( $first_img ) ){ $first_img = '<img class="attachment_post_thumbnail" src="' . get_stylesheet_directory_uri() . '/assets/img/common/no-img.jpg" alt="No image" />'; } return $first_img; }

php_learn
質問者

補足

---- SELECT DISTINCT post_id ---- ここに書いてあるDISTINCTが重複させないための記述です。 実はこれもSQLで重複しないようにされていたのです。 A.解説ありがとうございます。覚えておきます。 どういうことかというと、DISTINCTは取得項目の値がすべて同じものは一行にする、と言うものです。 (2)comment_dateがある方は、comment_post_IDとcomment_contentが同じでもcomment_dateが違うためにcomment_post_IDが重複して別々の行になっています。 (3)comment_dateがない方は、comment_post_IDとcomment_contentが同じであればその分が一行になるので、コメント文が同じcomment_post_IDは重複しないですが、コメント文が違うcomment_post_IDは重複しています。 (1)comment_post_IDだけのものはcomment_post_IDが同じであればその分が一行になるので、項目がひとつの場合は重複するものはひとつもないようになります。 A.例題まで出していただきありがとうございます。勉強になりました。SELECT DISTINCT post_idとしたのは取得項目に($result->post_id)で渡していたからですね。

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.17

・インストール時に名前を聞かれていたんですがあれはセキュリティの為だったんですね初めて知りました。 すみません、完全に私の想像で憶測です。 念のため調べてみました。 データベースのテーブル接頭辞とは?意味と変更方法を解説【WordPress】 https://rilaks.jp/wordpress/table-prefix/ こちらのサイトに同じようなことが書かれていましたので、間違いではなさそうでよかったです。

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.16

・別名を付けていたら変化しない、付けると変化するということでしょうか… ややこしい説明をしてすみませんでした。 別名を付けていたら付けた名前に変化し、付けなければもとの名前のまま、です。 現在は項目に別名を付けていませんのでこうなっています。 ---- ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id 省略 ) AS category ---- なので、これらの項目を外側で記述するには、それぞれ以下のようになります。 category.name category.slug category.object_id category.term_id sub_aの項目だったり、sub_cの項目だったりしたものが、項目名はそのままでcategoryの項目になった感じになります。 項目に別名を付けた場合は、例えば以下のような別名にしたとすると、 ---- ( SELECT sub_a.name AS category_name, sub_a.slug AS category_slug, sub_c.object_id AS category_post_id, sub_a.term_id AS category_id 省略 ) AS category ---- 外側で記述するにはこうなります。 category.category_name category.category_slug category.category_post_id category.category_id こうして見るとcategoryと言うテーブルの項目になったような感じが増すような気がします。

php_learn
質問者

補足

外側で記述するにはこうなります。 category.category_name category.category_slug category.category_post_id category.category_id こうして見るとcategoryと言うテーブルの項目になったような感じが増すような気がします。 A.第2テーブルのような形になるのですね勉強になりました。 ありがとうございます。 今からホーム画面に出力しているものと同じ項目を出力するようにコードを組んでみます。 リンクとカテゴリーフィールドの部分は正解がわかっていないためそのまま記述すると思いますが、よろしくお願いいたします。

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.15

PHPコードにするときは基本的にそのままです。 検索文字の条件がないのでそれを追加しました。 ---- <?php $search_query = get_search_query(); ?> <?php global $wpdb; ?> <?php $sql = " SELECT post.post_title, post.post_date, post.post_excerpt, post.comment_count, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' AND post.post_status = 'publish' AND (post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) GROUP BY post.ID ORDER BY post.post_date DESC "; $query = $wpdb->prepare($sql, "%$search_query%", "%$search_query%", "%$search_query%"); $results = $wpdb->get_results($query); ---- 以前はテーブル名にPHP変数を使っていましたが、SQL文が完成するまではそのままのテーブル名で書くことにしておきます。 他の人たちはどのようにしているのかわかりませんが、私はこのままでもいいかなと思っています。 ただ、WordPressインストール時に、テーブル名の前につける文字を設定されたと思いますが、それが初期値の「wp_」ではない場合は変数にする必要があります。 なぜテーブル名の前につける文字が設定できるようになっているかですが、私が想像するにふたつの意味があります。 ひとつは、データベースはひとつに対して、WordPressを複数インストールするためで、2回目のインストールでは「wp2_」とかつけたりすることでそれができます。 もうひとつは、セキュリティーに配慮したもので、もし初期値のまま「wp_」を使っていると、WordPressをちょっとでも知っている人が「wp_posts」に対して攻撃しようとします。そんなに簡単に突破はできないとは思いますが、テーブル名が知られているので、もし攻撃が成功した場合は投稿記事のデータがどうにかなったり、全部読み込まれたりするかも知れません。 しかし、テーブル名の前につける文字を例えば「qazwsxedc_」のようにでたらめで長くしておくと、これを推測して攻撃するのは困難になるのでより安全にはなります。 「wp2_」にしても、セキュリティー的により安全にするにしても、自分でSQL文を考えて記述する際にそれを書くのは面倒ですし間違えやすくなります。 それを楽にするのがテーブル名にPHP変数を使う方法です。 例えば、上記のSQL文の中のwp_postsをすべて{$wpdb->posts}と書いておけば、勝手に「wp2_posts」とか「qazwsxedc_posts」になってくれるわけです。 今のところ「wp_」であれば、phpMyAdminでSQL文を考えながら作る時も、それをPHPコードに転記するのも同じものなのでPHP変数を使うまでもありません。 最終的にできあがってから、PHP変数にする方向でいいと思います。

php_learn
質問者

補足

PHPコードにするときは基本的にそのままです。 検索文字の条件がないのでそれを追加しました。 ---- <?php $search_query = get_search_query(); ?> <?php global $wpdb; ?> <?php $sql = " SELECT post.post_title, post.post_date, post.post_excerpt, post.comment_count, //追加文 続きを読む post.concat('/articles/',post-ID.html)as post_name, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' //追加文 カスタムフィールドで選別 WHERE wp_postmeta.meta_key ='single_rss_feed1' AND post.post_status = 'publish' AND (post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) GROUP BY post.ID ORDER BY post.post_date DESC "; $query = $wpdb->prepare($sql, "%$search_query%", "%$search_query%", "%$search_query%"); $results = $wpdb->get_results($query); ---- A.インストール時に名前を聞かれていたんですがあれはセキュリティの為だったんですね初めて知りました。 $wpdb->は構文の1つとして認識していたのですが重要な役割があるんですね勉強になりました。ありがとうございます。 続きをよむのリンク取得と、カテゴリーフィード名で記事の選別を行うコードを書き忘れていたので追加してみましたが、問題なさそうでしょうか? //追加文で追加しております。 全体に対してカテゴリーフィードsingle_rss_feed1限定で取得させたいのですが、wp_postmetaが記事の軸になっておりmeta_keyがカテゴリーイールドの 指定にあたるので全体に対するWHEREで問題ないと思っているのですが… 以前はすべての項目に対し、$result->post_idを渡すことで記事重複表示を避けていたのですが、こちらは$SQLで対策をしている場合必要ないのでしょうか? $results = $wpdb->get_results($wpdb->prepare(" SELECT DISTINCT post_id FROM wp_postmeta INNER JOIN $wpdb->wp-posts INNER JOIN wp_comment INNER JOIN wp_terms ON post_id = ID

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.14

・sub_a=AS categoryになるのでしょうか? 副問い合わせの説明をしてなかったですね。 ---- ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ---- このカッコの中が副問い合わせのSQL文になります。 中のSQL文だけを実行することができますので試してみてください。 それ自体にすごく意味があるわけではないのですが、実行すれば結果を取得できます。 この結果をさもひとつのテーブルのような感じにするのが副問い合わせです。 そのテーブルのようなものにcategoryと言う別名を付けています。 なのでsub_aがcategoryなのではなく、このカッコそのものがcategoryです。 合体させたSQLにちょっとぬけがありました。 wp_terms sub_a ここも別名だったので、こうしておくべきでした。 wp_terms AS sub_a ではそのカッコの中がどうなっているのかですが、流用したままでsub_~はあまり深く考えなくてもいいかなと思っています。 と言うのも無責任ですね。 参考サイトでは別名がa、b、cのような一文字で書かれています。 この一文字がこのサイトのルールだとします。 メインとなるSQL文(私はこれを一番外側のSQL文と呼んでいます)に対して、副問い合わせとなるSQL文にも一文字ルールのa、b、cがあるのですが、それが副問い合わせだとわかるように副の文字の通りサブを意味するsub_を前につけて、sub_a、sub_b、sub_cとなっているようです。 別名はどのように付けても自由なのでそれはそれでいいとして。 sub_aはwp_terms、 sub_bはwp_term_taxonomy、 sub_cはwp_term_relationshipsとなっています。 それぞれをこのようにJOINすれば、投稿記事のIDと関連付けることができる項目が取得できるようです。 関連付けているのがこれで、 ---- ON post.ID = category.object_id ---- post.IDは投稿記事のIDです。 category.object_idが関連付けるための項目です。 カッコの中だけを実行して結果を見ていただくとわかりますが、 sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id と書いてあるのに、取得した結果の列見出しを見ると、 name、slug、object_id、term_idになっていると思います。 それぞれの前に書いているsub_aやsub_cは捨てられています。 カッコの中でのテーブル名と項目名は、取得結果にもカッコの外にも関係ないからです。 それぞれの項目名はその外に出たときにAS categoryでcategoryの項目としてあつかわれます。 そのため関連付けのONではcategory.object_idと言うものになっています。 その実態はsub_c.object_idです。 カッコの中で別名を付けていないので、そのままの項目名で外に出てきます。 wp_termsはカテゴリー情報ですがカテゴリー以外の情報もありそうです。 wp_term_taxonomyがwp_termsの付属情報のようで、taxonomyに以下のような種類があるようです。 'category': 記事カテゴリ 'link_category': リンクカテゴリ 'post_tag': タグ wp_term_relationshipsはwp_postsとの関連付けのためのテーブルのようです。 画像で使ったwp_postmetaも関連付けのような役割をしていたので似たようなものだと思います。

php_learn
質問者

補足

この結果をさもひとつのテーブルのような感じにするのが副問い合わせです。 そのテーブルのようなものにcategoryと言う別名を付けています。 なのでsub_aがcategoryなのではなく、このカッコそのものがcategoryです。 合体させたSQLにちょっとぬけがありました。 wp_terms sub_a ここも別名だったので、こうしておくべきでした。 wp_terms AS sub_a A.修正ありがとうございます。 sub_aはwp_terms、 sub_bはwp_term_taxonomy、 sub_cはwp_term_relationshipsとなっています。 それぞれをこのようにJOINすれば、投稿記事のIDと関連付けることができる項目が取得できるようです。 関連付けているのがこれで、 ---- ON post.ID = category.object_id ---- post.IDは投稿記事のIDです。 category.object_idが関連付けるための項目です。 カッコの中だけを実行して結果を見ていただくとわかりますが、 sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id と書いてあるのに、取得した結果の列見出しを見ると、 name、slug、object_id、term_idになっていると思います。 それぞれの前に書いているsub_aやsub_cは捨てられています。 カッコの中でのテーブル名と項目名は、取得結果にもカッコの外にも関係ないからです。 A.後にsub_a,b,cの答えがあったのですね、何かの略称かと勘違いしておりました。勉強になります。名前を作っていてもテーブルに影響はないということですね。 解説ありがとうございます。 それぞれの項目名はその外に出たときにAS categoryでcategoryの項目としてあつかわれます。 そのため関連付けのONではcategory.object_idと言うものになっています。 その実態はsub_c.object_idです。 カッコの中で別名を付けていないので、そのままの項目名で外に出てきます。 A.別名を付けていたら変化しない、付けると変化するということでしょうか… wp_termsはカテゴリー情報ですがカテゴリー以外の情報もありそうです。 wp_term_taxonomyがwp_termsの付属情報のようで、taxonomyに以下のような種類があるようです。 'category': 記事カテゴリ 'link_category': リンクカテゴリ 'post_tag': タグ wp_term_relationshipsはwp_postsとの関連付けのためのテーブルのようです。 画像で使ったwp_postmetaも関連付けのような役割をしていたので似たようなものだと思います。 A.IDとして使うものを連結したと認識していたのですが、wp_term_relationshipsは関連付けのためのテーブルだったのですね、覚えておきます。

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.13

・GROUP_CONCAT関数で記事別の投稿データとして扱うことができるという認識でしょうか? 投稿データと言うのがちょっとわかりませんが、たぶんそう言う認識でいいと思います。 記事別にまとめられたデータなのでそれを一件ごとにどうにか加工することになりますが、記事とカテゴリー(本来複数あるがひとつにまとめられているため)が一対一になっています。 ・これは投稿記事のスラッグとIDを結びつけて表示しているのではないでしょうか?それともスラッグというフィールドがあるのでしょうか? カテゴリーと言うか、wp_termsにもスラッグというフィールドがあります。 投稿記事のスラッグではないので大丈夫です。 データベース構造の説明には「term スラッグ。term 名を URL で扱いやすい形にしたもの」とあります。 HTMLのリンクの文字にはwp_termsのnameを使い、hrefにはwp_termsのslugを使うことになると思います。 ・a,とb,の違いが分からないのですが、idを渡したいテーブルということでしょうか? こんな感じで、aとかbだとさらにわからなくなってしまいますね。 先ほど合体させたSQL文の説明でも書きましたが、別名のASは省略できます。 このことを最初に説明しておけばよかったです。 aは何かというと、ここです。 FROM wp_posts a 書きかえると、 FROM wp_posts AS a となり、wp_postsのことです。 同じようにbはここで、 LEFT JOIN wp_users b 書きかえると、 LEFT JOIN wp_users AS b となり、wp_usersのことです。 つまりwp_postsにwp_usersをJOINして投稿者の情報を取得しています。 今のところ投稿者のことは考えていませんので、合体SQL文にはもってきていません。 それで前回のここですが、 ---- GROUP BY a.ID , a.post_date , a.post_modified , a.post_title , a.post_name , b.user_registered , b.user_login , b.user_nicename , b.display_name ---- 私が説明したかったのは、以下のようにSELECTに列挙されている項目のうち、グループ関数(ここではGROUP_CONCATのところ)を除いて他の項目をすべてGROUP BYに同じように書かなければいけない、と言うことです。 ---- SELECT a.ID , a.post_date , a.post_modified , a.post_title , a.post_name , b.user_registered , b.user_login , b.user_nicename , b.display_name , GROUP_CONCAT(c.name ORDER BY c.term_id) AS category_names/*変更*/ , GROUP_CONCAT(c.slug ORDER BY c.term_id) AS category_slugs/*変更*/ FROM wp_posts a (省略) GROUP BY a.ID , a.post_date , a.post_modified , a.post_title , a.post_name , b.user_registered , b.user_login , b.user_nicename , b.display_name (省略) ---- それがMySQLでは、これだけでも実行できます、と言うことでした。 ---- GROUP BY a.ID ----

php_learn
質問者

お礼

参考サイトを確認したところ、from wp_postsなので まとめてしまって問題内容ですが記事リンクを取得したい場合、続きをよむと関連付けるのは表示の際で問題ないでしょうか? 末尾は現状htmlにしていませんが可能であればSEOのために変更する予定です。 ※参考サイト https://webllica.com/select-post-list-from-mysql/ ※設定予定のパーマリンク https://●●.net/articles/post-●●.html SELECT post.post_title, post.post_date, post.post_excerpt, post.comment_count, post.concat('/articles/',post-ID.html)as post_name, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post

php_learn
質問者

補足

sub_a=AS categoryになるのでしょうか?今までの流れだとFROM wp_posts a書き換えるとAS category_slugsになると思うのですが…       subと名付けられているので前者のようにAS categoryではないかと思っております。 sub_c   Cはcategoryと認識しています。 LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' AND post.post_status = 'publish' GROUP BY post.ID ORDER BY post.post_date DESC ---- GROUP BY a.IDというのは便利なものということですね覚えておきます。ありがとうございます。

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.12

合体させるとこんな感じです。 もともとこちらでやっていたものに、参考サイトから必要なものだけを利用するかたちです。 必要なのはカテゴリーのところだけですので、こんな感じです。 ---- SELECT post.post_title, post.post_date, post.post_excerpt, post.comment_count, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' AND post.post_status = 'publish' GROUP BY post.ID ORDER BY post.post_date DESC ---- 参考サイトでは、別名をaとかbとかにされていて短さを優先されていましたが、増えてくるとわかりづらくなるので、cだったところをcategoryに変えています。 また、別名を記述する際のASは省略できるため参考サイトでは省略されていましたが、それも私はあまりいいとは思っていません。 なぜかと言うと、他人が書いたおそらく問題がひそんでいるとあるSQL文を解釈しようと見ている際に、項目の区切りのカンマを忘れたのか、別名を付けようとしているのかがわからなくて困ったことがあるからです。 他には、改行やカンマの位置を調整しました。 現段階では質問者さまはいろいろ探してコピー&ペーストされているのでどうしようともどうすることもなくそのままを流用することが重要なところですが、慣れてくると自分の好みの書き方と言うものが多くの人にはあります。 私の普段の書き方に近い感じでは書いていますが、わかりづらくならないように配慮したつもりでやっていますので、ご自分でSQL文を理解して読めるようになられたら、見やすいようにされたらいいと思います。 それも、コピーしている間はなかなかですが、自分で全部書くようになってくるとだんだんわかってくると思います。

php_learn
質問者

お礼

最新の質問になります。 以前書いていた下記のコードのprepareに渡すことになると思うのですが、SELECT DISTINCT post_id~の初めの渡し方が分かりません。 そちらについてのアドバイスをよろしくお願いいたします。 初めに組んでいたコードがSQLだと勘違いしていたようで、途中から混ざってしまっています… <?php $search_query = get_search_query(); ?> <?php global $wpdb; ?> $results = $wpdb->get_results($wpdb->prepare(" SELECT DISTINCT post_id FROM wp_postmeta INNER JOIN $wpdb->wp-posts INNER JOIN wp_comment INNER JOIN wp_terms ON post_id = ID WHERE wp_postmeta.meta_key ='single_rss_feed1' AND post_status = 'publish' AND ({$wpdb->posts}.post_content LIKE %s OR {$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_excerpt LIKE %s) "; $results = $wpdb->get_results(); ?> <?php if ($results) : ?> <ul> <?php foreach ($results as $result) : ?> <li> </li> <?php endforeach; ?> </ul>

php_learn
質問者

補足

回答ありがとうございます 下記サイトの情報がパーマリンクの参考になりそうなのでこちらを元にSQLを考えてみます https://webllica.com/select-post-list-from-mysql/

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.11

訂正します。 他のデータベースではグループ関数を使っている項目以外の取得項目すべてをORDER BYに書く必要があります。 ORDER BYではなくてGROUP BYでした。

php_learn
質問者

お礼

続きを読むに関してなのですが、 パーマリンク設定を変更したら(それに付随して)変わります。 との事だったので再度調べてみます。 URLをカスタムにして下記のようにしたいのですが、取得が難しいようであれば、月と投稿名 – 投稿月とタイトルを用いた構造 (例) http://www.example.com/2008/03/sample-post/ にすることを考えています。 articles/post-●●.html テーブルやフィールドがなくリンクに対して変わるようです。

php_learn
質問者

補足

GROUP_CONCAT関数はグループ化に基づいて指定した項目を行からひとつの項目に連結してくれるものです。 例えば、手を加える前の取得がこんな感じだった場合、 ---- 投稿記事1 カテゴリ-1 投稿記事1 カテゴリー2 投稿記事2 カテゴリー1 投稿記事2 カテゴリー3 投稿記事3 カテゴリー3 ---- この関数を使うとこうなります。 ---- 投稿記事1 カテゴリ-1,カテゴリー2 投稿記事2 カテゴリー1,カテゴリー3 投稿記事3 カテゴリー3 ---- これで投稿記事が重複しなくなり、カテゴリーがひとつの項目として取得できるようになります。 あとはPHPでカテゴリーの文字列を,(カンマ)で分割して処理することになります。 A.GROUP_CONCAT関数で記事別の投稿データとして扱うことができるという認識でしょうか? , sub_a.term_id/*追加*/ これは上記のORDER BY c.term_idで使うために追加しました。 GROUP_CONCATで結合する際の順序を指定するためです。 これがないとどうなるかわかりませんが、カテゴリー名とスラッグを別々の項目として取得しているのでその連結順序を一致させています。 この連結順序を一致させていないと、PHPで処理する際にカテゴリー名をカンマで分割したひとつ目とスラッグをカンマで分割したひとつ目が違うものになるかも知れないための安全策です。 A.1つ心配な点がありましてこれは投稿記事のスラッグとIDを結びつけて表示しているのではないでしょうか?それともスラッグというフィールドがあるのでしょうか? 後者であれば問題ないのですが、前者であればスラッグは1つ1つ違いますので、記事1つ1つに指定が必要でその分データが膨れます。 GROUP BY a.ID/*追加*/ これはグループ化するための書き方です。 何をしているかと言うと、a.ID(投稿記事のID)ごとにグループ化です。 試しに、参考サイトのもともとのSQL文にこれだけを追加してみてください。 それだけで投稿記事の重複がなくなります。 この重複をなくすのがグループ化です。 カテゴリー名とスラッグはもともと複数あったもののうちどれかひとつだけが取得されます。 どれが取得されたのか根拠不明の上、他のものが取得できなくなるのは困るので、先に説明したGROUP_CONCAT関数で全部を連結しているわけです。 A., GROUP_CONCAT(c.name ORDER BY c.term_id) AS category_names/*変更*/ , GROUP_CONCAT(c.slug ORDER BY c.term_id) AS category_slugs/*変更*/ GROUP BY a.ID/*追加*/ で記事の重複をなくしているんですね 余談ですが、MySQLはこのGROUP BYがとても楽です。 他のデータベースではこれだけでは済みません。 GROUP_CONCAT関数の他にもいろいろあるのですが、それらをまとめてグループ関数と呼びます。 他のデータベースではグループ関数を使っている項目以外の取得項目すべてをORDER BYに書く必要があります。 ---- GROUP BY a.ID , a.post_date , a.post_modified , a.post_title , a.post_name , b.user_registered , b.user_login , b.user_nicename , b.display_name ---- A.a,とb,の違いが分からないのですが、idを渡したいテーブルということでしょうか?また前日のコードと組み合わせる場合、a.post_excerpt、a.postcomment=pv_count 、a.attachment.guid AS thumnail.urlとなるのでしょうか? 合体させると下記のような形になるのでしょうか? SELECT a.ID , a.post_date , a.post_modified , a.post_title , a.post_name ,a.post_excerpt ,a.postcomment=pv_count ,a.attachment.guid AS thumnail.url , b.user_registered , b.user_login , b.user_nicename , b.display_name , GROUP_CONCAT(c.name ORDER BY c.term_id) AS category_names/*変更*/ , GROUP_CONCAT(c.slug ORDER BY c.term_id) AS category_slugs/*変更*/ FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID //ここから追記 FROM wp_posts a LEFT JOIN wp_users b ON a.post_author = b.ID LEFT JOIN ( SELECT sub_a.name , sub_a.slug , sub_c.object_id , sub_a.term_id/*追加*/ FROM wp_terms sub_a LEFT JOIN wp_term_taxonomy sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) c ON a.ID = c.object_id    WHERE a.post_status = 'publish'  AND a.post_type = 'post'  GROUP BY a.ID/*追加*/    ORDER BY a.post_date ASC    WHERE    post.post_type = 'post'    AND    post.post_status = 'publish'    ORDER BY    post.post_date DESC

  • dell_OK
  • ベストアンサー率13% (741/5649)
回答No.10

お礼 2022/04/27 22:07 WordPressに投稿した記事一覧をSQLで取得するメモ https://www.agent-grow.com/self20percent/2017/04/20/get-articles-list-from-database-of-wordpress/ こちらのサイトのSQL文はとても参考になりますね。 楽できそうです。 試しに実行されてみたでしょうか。 カテゴリーを複数指定した投稿記事が重複して取得されたと思います。 これを解決する方法はあまり難しくはありません。 手を加えたSQL文はこちらです。 ---- SELECT a.ID , a.post_date , a.post_modified , a.post_title , a.post_name , b.user_registered , b.user_login , b.user_nicename , b.display_name , GROUP_CONCAT(c.name ORDER BY c.term_id) AS category_names/*変更*/ , GROUP_CONCAT(c.slug ORDER BY c.term_id) AS category_slugs/*変更*/ FROM wp_posts a LEFT JOIN wp_users b ON a.post_author = b.ID LEFT JOIN ( SELECT sub_a.name , sub_a.slug , sub_c.object_id , sub_a.term_id/*追加*/ FROM wp_terms sub_a LEFT JOIN wp_term_taxonomy sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) c ON a.ID = c.object_id WHERE a.post_status = 'publish' AND a.post_type = 'post' GROUP BY a.ID/*追加*/ ORDER BY a.post_date ASC ---- , GROUP_CONCAT(c.name ORDER BY c.term_id) AS category_names/*変更*/ , GROUP_CONCAT(c.slug ORDER BY c.term_id) AS category_slugs/*変更*/ GROUP_CONCAT関数はグループ化に基づいて指定した項目を行からひとつの項目に連結してくれるものです。 例えば、手を加える前の取得がこんな感じだった場合、 ---- 投稿記事1 カテゴリ-1 投稿記事1 カテゴリー2 投稿記事2 カテゴリー1 投稿記事2 カテゴリー3 投稿記事3 カテゴリー3 ---- この関数を使うとこうなります。 ---- 投稿記事1 カテゴリ-1,カテゴリー2 投稿記事2 カテゴリー1,カテゴリー3 投稿記事3 カテゴリー3 ---- これで投稿記事が重複しなくなり、カテゴリーがひとつの項目として取得できるようになります。 あとはPHPでカテゴリーの文字列を,(カンマ)で分割して処理することになります。 , sub_a.term_id/*追加*/ これは上記のORDER BY c.term_idで使うために追加しました。 GROUP_CONCATで結合する際の順序を指定するためです。 これがないとどうなるかわかりませんが、カテゴリー名とスラッグを別々の項目として取得しているのでその連結順序を一致させています。 この連結順序を一致させていないと、PHPで処理する際にカテゴリー名をカンマで分割したひとつ目とスラッグをカンマで分割したひとつ目が違うものになるかも知れないための安全策です。 カテゴリー名とスラッグを別々にせずひとつの項目として取得する方法もあります。 c.term_idを追加しなかったとして、 GROUP_CONCAT(c.name,c.slug) これでカテゴリー名とスラッグがひとつにくっついて取得できます。 つまり順序が一致している、と言うか、ひとつになっているので順序が不要です。 とは言え、表示の際に、ある投稿記事のカテゴリーの順序と別の投稿記事のカテゴリーの順序がばらばらかも知れなくなります。 またこれはこれでPHPの処理でさらに分割しなければならなくなるので、どうしたものかって感じです。 SQL実行効率で言うとこちらの方がいいのは確かです。 どちらに重点を置くかですがデータベースに負荷とPHPに負荷と言うのはデータが膨大にならないと決めがたいものですし、サイト運営のさなかでバランスをはかればいいと思いますので、今は前者の方法でいいと思います。 GROUP BY a.ID/*追加*/ これはグループ化するための書き方です。 何をしているかと言うと、a.ID(投稿記事のID)ごとにグループ化です。 試しに、参考サイトのもともとのSQL文にこれだけを追加してみてください。 それだけで投稿記事の重複がなくなります。 この重複をなくすのがグループ化です。 カテゴリー名とスラッグはもともと複数あったもののうちどれかひとつだけが取得されます。 どれが取得されたのか根拠不明の上、他のものが取得できなくなるのは困るので、先に説明したGROUP_CONCAT関数で全部を連結しているわけです。 余談ですが、MySQLはこのORDER BYがとても楽です。 他のデータベースではこれだけでは済みません。 GROUP_CONCAT関数の他にもいろいろあるのですが、それらをまとめてグループ関数と呼びます。 他のデータベースではグループ関数を使っている項目以外の取得項目すべてをORDER BYに書く必要があります。 ---- GROUP BY a.ID , a.post_date , a.post_modified , a.post_title , a.post_name , b.user_registered , b.user_login , b.user_nicename , b.display_name ---- なぜMySQLはすべてを書かなくてもいいようにしているのかわかりませんが、他のデータベースでは当然(エラーになる)ですが、MySQLでも書くようにした方がいいとは思います。 ただ、SQL文を試行錯誤で考えている間は、取得項目が増えたり減ったりするので、毎回書きかえていると面倒ですし間違えたりしてエラーになるかも知れません。 なのでSQL文が完成するまではa.IDだけでいいと思います。 a.IDと言っていますが、これもJOINの時に話したユニークが重要で、これだけでグループ化のキーとなる項目でなければいけません。 これを説明するいい例が参考サイトのもともとのSQL文では作れないので今はやめておきます。

関連するQ&A

  • WordPressの質問(q10032703)の続

    該当コードからmeta_keyに当てはまる記事を出力したいが、記事が何も表示されない。 function set_template_info() { global $tn; global $tk; global $rss_table_name; global $current_page; $tn = get_template_number(); $tk = get_template_key($tn); $rss_table_name = get_rss_table_name($tn); $current_page = get_current_page(); } function get_template_number() { global $template; $template_number = $_GET['tn']; switch ($template_number) { case '2': break; case '3': break; default: switch (pathinfo($template, PATHINFO_FILENAME)) { case 'page-secound': $template_number = 2; break; case 'page-third': $template_number = 3; break; default: $template_number = 1; } } return $template_number; } function get_template_key($template_number) { if (1 == $template_number) { $template_key = 'single_rss_feed1'; } elseif (2 == $template_number) { $template_key = 'double_rss_feed2'; } elseif (3 == $template_number) { $template_key = 'triple_rss_feed3'; } return $template_key;

    • ベストアンサー
    • PHP
  • RSSと投稿記事を交互に表示させたい

    内容の修正が必要ですが原因がわかりません 1.投稿に画像やカテゴリーなどが表示されず、タイトルと日付けのみ表示されている 2.RSS画像にURLがついておらず画像のみ表示されている 3.RSSの画像がない場合ダミー画像を表示させたいが書き方が調べてもわからない <?php $dbh = connect_db(); $categories = []; foreach (get_categories() as $category) { $categories[$category->cat_ID] = $category; } function set_other_data($post) { // アイキャッチIDを取得 $post_thumbnail_id = get_post_thumbnail_id($post); // アイキャッチ画像の確認 if ($post_thumbnail_id) { // 存在する $image_src = wp_get_attachment_image_src($post_thumbnail_id); // サムネイルの画像URLを設定 $post->thumbnail = $image_src[0]; } else { // 存在しない $post->thumbnail = 'noimage.jpg'; } // カテゴリーIDを取得 $post->categories = wp_get_post_categories($post->ID); // コメントテキスト if (0 == $post->comment_count) { // コメントなし $post->comments = __('No Comments'); } else { // コメントあり $post->comments = $post->comment_count.'件のコメント'; } // コメントリンク $post->comments_link = get_comments_link($post->ID); } delete_old_rss($dbh);//接続オブジェクトを渡す //RSS保存 $dbh = connect_db();//① $stmt = $dbh->prepare('insert into rss_feed (title, link, date, img) values (?, ?, ?, ?) on duplicate key update title=?, link=?, date=?, img=?');//② $url1 = get_rss_site_url(); foreach ($url1 as $url) { if (($rss = @simplexml_load_file($url)) === false) { continue; } foreach ($rss->item as $item) { $dc = $item->children('dc', true); $date = date('Y-m-d H:i:s', strtotime($dc->date)); if ($date < $delete_date) { continue; } $title = $item->title; $link = $item->link; $content = $item->children('content', true); $result = preg_match('/<img[^>]*src=\"([^"]+)\"[^>]*>/i', $content->encoded, $matches); if (1 == $result) { $img = $matches[1]; } else { $img = ''; } $stmt->execute([$title, $link, $date, $img, $title, $link, $date, $img]); } } if (ctype_digit($_REQUEST['page'])) { $current_page = (int) $_REQUEST['page']; } else { $current_page = 1; } if ($current_page > $wp_query->max_num_pages) { $current_page = $wp_query->max_num_pages; } $block_per_page = 2; $rss_per_block = 18; $posts_per_block = $wp_query->post_count / $block_per_page; //RSS読み込み $rss_per_page = $block_per_page * $rss_per_block; $rss_offset = ($current_page - 1) * $rss_per_page; $sql = 'SELECT * FROM rss_feed ORDER BY date DESC LIMIT ?,?'; $stmt = $dbh->prepare($sql); $stmt->bindParam(1, $rss_offset, PDO::PARAM_INT); $stmt->bindParam(2, $rss_per_page, PDO::PARAM_INT); $stmt->execute(); $rss_items = $stmt->fetchAll(PDO::FETCH_OBJ); $posts_per_page = $block_per_page * $posts_per_block; $posts_offset = ($current_page - 1) * $posts_per_page; $args = [ 'posts_per_page' => $posts_per_page, 'offset' => $posts_offset, ]; $post_items = get_posts($args); //表示 for ($i = 0; $i < $block_per_page; ++$i) { echo '<h2>ブロック</h2>'; echo '<h3>RSS</h3>'; for ($j = 0; $j < $rss_per_block; ++$j) { $item_index = $i * $rss_per_block + $j; if ($item_index >= count($rss_items)) { break; } $item = $rss_items[$item_index]; echo '<ul>'; echo "<li class=\"sitelink\"><a href=\"{$item->link}\">{$item->title}</a></li>"; echo "<li class=\"sitelink\"><a href=\"{$item->link}\">site</a></li>"; echo "<li class=\"sitedate\">{$item->date}</li>"; if (!empty($item->img)) { echo "<li><img src=\"{$item->img}\" width=\"100\"></li>"; } echo '</ul>'; } echo '<h3>投稿</h3>'; for ($j = 0; $j < $posts_per_block; ++$j) { $item_index = $i * $posts_per_block + $j; if ($item_index >= count($post_items)) { break; } $item = $post_items[$item_index]; echo '<ul>';   echo "<li><a href=\"{$item->guid}\">{$item->post_title}</a></li>"; echo "<li>{$item->post_date}</li>"; echo '</ul>'; } }

    • ベストアンサー
    • PHP
  • WordpressのRSS取得条件

    以下のコードに2010年以降のフィードのみ表示させるようにするにはどうすればよいですか? <?php include_once(ABSPATH . WPINC . '/feed.php'); $rss = fetch_feed(array('RSSフィード')); if (!is_wp_error( $rss ) ) : $rss->set_cache_duration(1800); $rss->init(); $maxitems = $rss->get_item_quantity(10); $rss_items = $rss->get_items(0, $maxitems); date_default_timezone_set('Asia/Tokyo'); endif; ?> <dl> <?php if ($maxitems == 0) echo '<dt>No items.</dt>'; else foreach ( $rss_items as $item ) : ?> <dt> <?php echo $item->get_feed()->get_title(); ?><br /> <a href='<?php echo $item->get_permalink(); ?>' target="_blank"><?php echo $item->get_title(); ?></a> </dt><?php endforeach; ?></dl>

    • 締切済み
    • PHP
  • Wordpressにおいてカスタム投稿の読み込み

    Wordpressにて美容系ポータルサイトを作っています。 お店情報のカスタム投稿 口コミのカスタム投稿 の二つ、そしてトップページとの連動を作りたいと思っています。 まずはお店情報にはサロン名やら営業時間やらキャンペーンメニューなどがポストタイプ(salon_posttype)にて入っています。 口コミには行ったサロン名や、感想、名前などがポストタイプ(review_posttype)で入っています。 そこでお店情報のページに、 そのお店の口コミの投稿を表示させたいと思っています。 つまり、review_posttypeにて入れた、'salonname'のキーがそのページのページ名=(サロン名)と同じであれば表示、で行けるかなと構文を書きましたが、ここからがわかません。 <?php query_posts('&post_type=review_posttype'); while(have_posts()) : the_post(); ?> <?php if( get_post_meta(get_the_ID(), 'salonname', true) != '' ):?> ↑↑↑ここを"もしsalonname=今見ているページの題名なら"にしたいです。↑↑↑ <p class="title"><?php echo get_post_meta(get_the_ID(), 'salonname', true);?></p> <p class="naiyou"><?php echo get_post_meta(get_the_ID(), 'review_naiyou', true);?></p> <p class="detail"><a href="<?php the_permalink() ?>">詳しくはこちら</a></p> <?php endif;?> <?php endwhile; ?> <?php wp_reset_query(); ?> どこをどうしたらいいでしょうか?そもそもここまでも合っていますか?

    • 締切済み
    • PHP
  • WordpressでテンプレにIDを表示できない…

    現在、初めてWordpressのテンプレートを作っています。 そこで、カスタマイズ方法についてお伺いさせてください。 行いたいこととしては、特定のIDの場合、特定の文言を表示というシンプルなカスタマイズです。 対象としているページは単一記事の投稿(single.php)です。 今回仮にカテゴリIDが10を対象としてみます。 その場合、以下のように記述しています。 <?php if(is_category('10')): ?> <p>カテゴリのIDが10のメッセージ!</p> <?php else: ?> <p>それ以外のメッセージ!</p> <?php endif; ?> と記述しています。 ちなみに、デフォルトのテンプレートを使うと上手く表示できるのですが、今回自分で作っているテンプレートなので、それが問題だと思います。 カテゴリID番号をテンプレート側で出力していない為、上手く動作しないのかな?と思いsingle.phpには こんな感じで記述してみました。 <?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); ?> <?php $post_cat=get_the_category(); $cat_id=$post_cat[0]->cat_ID; ?> <?php $post_cat=get_the_category(); $cat=$post_cat[0]; ?> <div class="entry" id="category-<?php echo $cat->cat_ID ?>"> ↑これでページ上には一応、 <div class="entry" id="category-10">とカテゴリIDが10として表示されています。 しかしながら、前述した<p>カテゴリのIDが10のメッセージ!</p>というメッセージが表示されません…。 カテゴリIDが一致しているのに、何故分岐の処理が行われないのでしょうか?何か根本的に間違っていますでしょうか。 WPのテンプレートカスタマイズにお詳しい方いらっしゃいましたら、アドバイスをいただけませんでしょうか。よろしくお願いします。 再度お伝えいたしますが、デフォルトのテンプレートに <?php if(is_category('10')): ?> <p>カテゴリのIDが10のメッセージ!</p> <?php else: ?> <p>それ以外のメッセージ!</p> <?php endif; ?> こちらを入れると表示されますので、この部分は問題ないのかと思います。 宜しくお願いします。

  • wordpressの投稿記事が日付順に並ばない

    初めまして。wordpressについてお聞きしたいのですが、 どなたか詳しい方、教えて頂けないでしょうか。 カスタム投稿で作った記事のタイトルと日付を抽出して、新着情報一覧を作りました。 この投稿記事を、新着順にソートして並べたいのですが、不具合がでて困っています。 普段はwordpressのデフォルトの設定通り、最新の日付順に表示されているのですが、 たまに、古い記事の下に新着記事が表示されてしまうのです。 例えば8/1に投稿した記事の下に、最新の8/12の投稿が 表示されてしまいます。 プラグインは 「Post Types Order」と「postMash」を入れています。 このプラグインの不具合でおかしくなることはあるのでしょうか。 【ソース】 <?php query_posts('post_type=news&posts_per_page=6'); ?> <?php if(have_posts()): while(have_posts()): the_post(); ?> <?php get_template_part('content','title'); ?> <?php endwhile; endif; ?> 【仕様】 WordPress 2.9. PHP 5.2.17 データベース バージョン: MySQL 5.5 どうぞよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • WordPressにおいて、サブカテゴリーに画像を表示させる。

    WordPressにおいて、サブカテゴリーに画像を表示させる。 WordPress,PHP初心者です。 現在 情報サイトを作っているのですが、 あるカテゴリーのループ中に、サブカテゴリーにも属していると、画像を表示させたいです。 ショッピングサイト等で例を言うと 「シャツ」という大カテゴリーをループを使って一覧で出力し、 その中で、サブカテゴリー「売り切れ」や「NEW」にチェックを入れていると(管理画面で) それに適した画像が表示されるようにしたいのです。 ”「売り切れ」と「NEW」にどちらも属している場合もあります” なおかつ、そのサブカテゴリーにチェックが入っていると 上位に表示されると一層良いのですが。 ループの中で、更にループ処理?という考えがあまり正しくないような気がするのですが、 試している所やはりうまくいきません。 ソースは下記の通りです。 <!--大カテゴリーのループ開始--> <?php query_posts("cat=3&showposts=10"); ?> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div class="list-box"> <a href="<?php the_permalink() ?>"> <img src="<?php echo get_post_meta($post->ID,'faceimage',TRUE); ?>" alt="<?php the_title(); ?>" width="141" height="141" /> </a> <p class="name"><?php the_title(); ?></p> <p class="size"><?php echo get_post_meta($post->ID,'textfield',TRUE); ?></p> <!--売り切れの場合、画像表示--> <?php query_posts("cat=4"); ?> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div class="ico-on"><img src="hogehoge" alt="売り切れ" /></div> <?php endwhile; ?> <?php endif; ?> <!--新着アイテムの場合、画像表示--> <?php query_posts("cat=6"); ?> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div class="ico-new"><img src="hogehoge2" alt="新着アイテム" /></div> <?php endwhile; ?> <?php endif; ?> </div> <!--ループ完全に終了--> <?php endwhile; ?> <?php endif; ?> 調べてみたものの、行き詰まっています。 稚拙な質問ではございますが、 どうぞご教授お願い致します。

  • WordPress PCとスマホで表示を切り替える

    PCでは記事一覧5件、スマホでは3件表示するようにしたいです。 条件分岐タグを使って、PCとスマートフォンで記事の一覧表示を切り替える方法がうまくいきませんでした。 https://handywebdesign.net/2017/11/wp-is-mobile/ 改造前のコード(問題なく表示できました) <ul> <?php $latest_posts = get_posts( array( 'posts_per_page' => 5, // 表示する記事の数 'category_name' => '投稿ID',// 投稿IDを取得 'fields' => 'ids', ) ); foreach( $latest_posts as $post ): setup_postdata( $post ); if( has_post_thumbnail() ) { $post_thumb = get_the_post_thumbnail( '', 'post_thumbnail' ); // アイキャッチがあるときはアイキャッチを表示 } else { $post_thumb = '<img src="' . get_template_directory_uri() . '/img/noimage.gif" width="100" height="100" alt="デフォルト画像" />'; // アイキャッチがないときは《noimage.gif》を表示 } $post_categories = get_the_category(); // カテゴリーを取得 $post_content = wp_trim_words( get_the_content(), 30, '…' ); // 30字分を抜粋 ?> <li <?php post_class(); ?>> <a href="<?php the_permalink(); ?>"> <div class="blogListimg"> <?php echo wp_kses_post( $post_thumb ); ?> </div> <!-- アイキャッチここまで --> <p class="post-time blogDt"><?php the_time('Y.m.d'); ?></p> <p class="post-categories blogCt"><?php echo esc_html( $post_categories[0]->name ); ?></p> <h3 class="post-title"><?php the_title(); ?></h3> <p class="post-content blogBf"><?php echo esc_html( $post_content ); ?></p> </a> </li> <?php endforeach; wp_reset_postdata(); ?> </ul> PCとスマートフォンで記事の一覧表示を切り替えるコード 参考サイトを参考にfunctions.phpにfunction is_mobile() コードを追加。 トップページのphpに以下を改造。 <?php if ( is_mobile() ) : ?> <?php $latest_posts = get_posts( array( 'posts_per_page' => 5, // 表示する記事の数 'category_name' => '投稿ID',// 投稿IDを取得 'fields' => 'ids', ) ); foreach( $latest_posts as $post ): setup_postdata( $post );  ・  ・  ・ <?php else: ?> <?php $latest_posts = get_posts( array( 'posts_per_page' => 3, // 表示する記事の数 'category_name' => '投稿ID',// 投稿IDを取得 'fields' => 'ids', ) ); foreach( $latest_posts as $post ): setup_postdata( $post );  ・  ・  ・ <?php endforeach; wp_reset_postdata(); ?> </ul> 結果は真っ白になってしまいました。 HTMLソースも真っ白です。 空白はSublime Textのテキストエディターを使っていますので、確認しております。 どこが違うか、教えてくださいますか? よろしくおねがいします。

    • ベストアンサー
    • PHP
  • WordPress 最新記事をまとめてURLにする

    参考のURL https://www.buzzhook.co.jp/ 下の方に「BACKYARD BLOG」があります。 アイキャッチ画像、年月日、カテゴリー、タイトル、抜粋全てどれをクリックしてもURLへジャンプします。 HTMLソースは下記になります。 <li> <a herf="#"> . . . </a> </li> WordPressのトップページも同様にしたいのですが、PHPプログラムはまだ初心者なので、うまくいきませんでした。結果はアイキャッチのみURLでした。 どこが違うのでしょうか? 宜しくお願いします。 <!-- main --> <main> <!-- 最新記事リスト --> <ul> <li> <a href="<?php the_permalink(); ?>"> <?php query_posts('posts_per_page=5'); ?> <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <!-- アイキャッチ表示 --> <?php if (has_post_thumbnail()) : ?> <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?></a> <?php else : ?> <a href="<?php the_permalink(); ?>"><img src="<?php bloginfo('template_url'); ?>/img/noimage.gif" width="100" height="100" alt="デフォルト画像" /></a> <?php endif ; ?> <!-- カテゴリー表示 --> <?php echo get_the_category()[0]->name; ?> <!-- 抜粋 --> <?php echo get_the_excerpt(); ?> <span class="date"> <?php the_time('Y年n月j日'); ?> <?php $days=30; $today=date('U'); $entry=get_the_time('U'); $diff1=date('U',($today - $entry))/86400; if ($days > $diff1) { echo '<img src="images/new.gif" alt="New" />'; } ?> </span> </a> </li> <?php endwhile; endif; ?> <?php wp_reset_query(); ?> </ul> <!-- 最新記事リストここまで --> </main>

    • ベストアンサー
    • PHP
  • ワードプレス 最新記事1件だけ大きく表示

    トップページに記事一覧をリストしたものを表示させます。 最新記事1件だけ大きく表示し、以降は普通にしたいです。 検索しましたところ、参考サイトを見つけました。 https://naifix.com/latest-article-new/ これらのプログラム記述が現在使用しているTeemaのプログラムが違っています。 以下が現在使用しているTeemaのプログラム(index.php) get_template_part( 'template-parts/content' 記事一覧リストは「template-parts」フォルダ内にある「content.php」 を使用するといったものです。 最新記事の1件だけ「content2.php」を使用し、以降は「content.php」 を使用するといった記述が分からないのです。 アドバイスをお願いします。 <?php if ( have_posts() ) : if ( is_home() && ! is_front_page() ) : ?> <header> <h1><?php single_post_title(); ?></h1> </header> <?php endif; while ( have_posts() ) : the_post(); get_template_part( 'template-parts/content', get_post_format() ); endif; ?>

    • 締切済み
    • PHP