• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:5つずつ15件の記事を分割して表示したい)

5つずつ15件の記事を分割して表示したい

このQ&Aのポイント
  • <?php $wp_query = new WP_Query(); $args = array( 'post_type' => 'post', 'posts_per_page' => 2, ); $wp_query->query($args); if ($wp_query->have_posts()) { $i = 0; while ($wp_query->have_posts()) { $wp_query->the_post(); $i++; if ($i > 2) break; } } ?>
  • <?php $wp_query = new WP_Query(); $args = array( 'post_type' => 'post', 'posts_per_page' => 2, ); $wp_query->query($args); $i = 0; while ($wp_query->have_posts()) { $wp_query->the_post(); $i++; if ($i > 7) continue; if ($i > 4) break; } ?>
  • The code is not displaying the articles because the loop condition and the break statement are not properly set.

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

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.26

FTPでテーマディレクトリにアップロードできなくて、 public_htmlにインストールすることになった場合は、 ローカルでのインストール先は「C:\xampp\htdocs」になると思います。

php_learn
質問者

お礼

もともとインストールされているcomposerにautoload.phpをインストールできないか試してみます。

php_learn
質問者

補足

ルートパス内に配置したかったのですが、セキュリティ上の問題があるようです。 オンライン環境である場合ルートパス配下の外側にファイルを設置する必要があるようですが、 レンタルサーバーのマニュアルではセキュリティ上の理由によりドキュメントルートをpublic_html配下以外にすることはできません。との記述があり、autoload.phpは扱えないと思われます。申し訳ありません。 composer 等の管理システムを使用して導入したファイル群は、公開ディレクトリに設置されることを想定していないものも多く、直接のアクセスをされると危険なものもあります。(サンプルコードとか怪しい) (テラテイルより引用) composer 等の管理システムを使用して導入したファイル群は、公開ディレクトリに設置されることを想定していないものも多く、直接のアクセスをされると危険なものもあります。(サンプルコードとか怪しい) ライブラリを使用するのにコードの挙動をすべて確認するのは本末転倒なので、普通はドキュメントルート外に置いて手間を省きます。 自身で安全が確認できないのであれば、ドキュメントルート内に設置はしないのが適切です。

その他の回答 (25)

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.25

「WordPressに後からcomposerを入れる幾つかの方法」の 「1. テーマにそのまま入れる」を参考に私も入れてみました。 私は「Twenty Twenty-One」と言うテーマを使っているので、 テーマのディレクトリの場所はここで、 C:\xampp\htdocs\wordpress\wp-content\themes\twentytwentyone composerでのインストール先になります。 インストールすると、 「vendor」ディレクトリが作成され、 その中に「autoload.php」が作成されています。 C:\xampp\htdocs\wordpress\wp-content\themes\twentytwentyone\vendor 質問者さまとはテーマが違うとは思いますが、 同じようなディレクトリ構成になっていると思います。 テスト用の「rss.php」の場所ですが、 前回、適当な場所にと言ったのはよくなかったですね。 すみませんでした。 ここからも「vendor」を参照するので、 テーマのディレクトリに配置してみてください。 簡単に言うと「index.php」と同じ場所です。 それで、以下のURLにアクセスすれば実行できると思います。 http://localhost/wordpress/wp-content/themes/twentytwentyone/rss.php require_once __DIR__.'/vendor/autoload.php'; この「__DIR__」はそのファイルの存在するディレクトリなので、 私の環境ではここを示します。 C:\xampp\htdocs\wordpress\wp-content\themes\twentytwentyone なので読み込む「autoload.php」はここになります。 C:\xampp\htdocs\wordpress\wp-content\themes\twentytwentyone/vendor/autoload.php 「index.php」でも同じように、 require_once __DIR__.'/vendor/autoload.php'; これで読み込むパスになります。 ローカルの環境としては、これで質問者さまとほぼ同じになったかと思います。 レンタルサーバーでcomposerが使えないとのことなので、 「vender」ディレクトリをサーバーのテーマディレクトリに FTPでアップロードできればいいのですが、それは可能でしょうか。 できればそれが一番よかったのですが、できないとなると、 public_htmlに入れてパスを通す方法になるのですね。 そうであれば、絶対パスとしては、 ~/public_html/vendor/ になるのかな。 public_htmlを簡単に取得する方法があるような気がするのですが、 とりあえず、dirnameをいくつか重ねて相対的に読み込んで大丈夫です。 「autoload.php」から「rss.php」で読み込むのではなく、 「rss.php」から「autoload.php」を読み込みます。 「autoload.php」から読み込むのは「SimplePie」などのファイルです。 「autoload.php」から先でいろいろなファイルが読み込まれる仕組みで、 それはcomposerからインストールした際に自動的に準備されるので、 直接手を加えることはないものです。 laravelについては、何度か試したことがあるのですが、 説明できるほどには習得していません。 laravelにも「autoload.php」がありましたか。 それはそれでcomposerの「/vendor/autoload.php」とは別のものかも知れません。 ただ、最初あるいはなるべく早い段階で読み込んでおく必要があるファイルを、 列挙しているのだと思います。

php_learn
質問者

お礼

すみません。書き込むところがなかったのでこちらで代用します。 エラーの該当箇所なのですが、wordpressを扱わないほうですとループの外にinsertを置くように数回注意されましたので。おそらくforeachで値を入れる前に空かどうかテーブルをチェックすることだと思われます。 dell_OKさんの環境で表示されているとしたら、レンタルサーバーのデフォルトの仕様でwordpressを通さずに、表示していることが原因かもしれません。 もう片方のほうも完成に近いので、そちらのほうもお聞きしたいことがあるのですが。 http://localhost/wordpress/wpcontent/themes/twentytwentyone/ // insertの準備 ループ内にあるのでデータがnullなのか確認できていないのではないのか? $wpdb->insert('rssfeed', ['title' => $title, 'link' => $link, 'thumb' => $thumb, 'content' => $content], ['%s', '%s', '%s', '%s']); <?php require_once( dirname( __FILE__ ) . '/wp-load.php' ); //ファイルの先頭で読み込む //RSSをまとめる $url1 = [ 'http://blog.livedoor.jp/dqnplus/index.rdf', 'http://alfalfalfa.com/index.rdf', 'http://himasoku.com/index.rdf', ]; // URLのループ開始 テーブルに格納 foreach ($url1 as $url) { $count = 0; $rss = simplexml_load_file($url);// simplexml_load_file()でRSSをパース解析してオブジェクトを取得します。 foreach ($rss->item as $item) {// 個別記事のループ開始 RSSの取得が始まる if ($count >= 8) { break; } ++$count; $title = (string) $item->title; //「$item->title」だけではうまくいかないのでstringにキャスト $link = (string) $item->link; //以下同じ $thumb = (string) $item->thumb->url; $thumbnail = '/images/dummy_thumbnail.jpg'; // 画像がない場合の代替画像 if ( $thumb ){ $thumbnail = $thumb; } $content = (string) $item->description;//詳細を取得 // insertの準備 ループ内にあるのでデータがnullなのか確認できていないのではないのか? $wpdb->insert('rssfeed', ['title' => $title, 'link' => $link, 'thumb' => $thumb, 'content' => $content], ['%s', '%s', '%s', '%s']); } } $results = $wpdb->get_results('SELECT * FROM rssfeed');//SELECT した結果を複数取得 $wpdb->get_results foreach ($results as $item) { echo $item->title.'<br>';//タイトルを表示 } ?> <?php $wpdb->show_errors(); ?>

php_learn
質問者

補足

レンタルサーバー側の仕様を見落としておりました。本当に申し訳ありません。 話が戻ってしまうのですが、データベースに保存して表示する(期間を区切ってデータのキャッシュを行う)方法を軸にコードを修正してみます。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.24

XAMPPでテストでしたら私と同じですね。 では、ローカルにはcomposerをインストールして、 SimplePieもインストールして動作している、 と言うことでいいでしょうか。

php_learn
質問者

お礼

あれから調べてみたり指摘をいただいたりして再度考えをまとめてみたのですが。 index.phpにはrequire_onceのみを記載しようと思います。 別のファイルにDB関連のものを記載して、表示のみindexにrequire_onceでphpファイルを指定します。 db.php(db関連)→page.php(表示のみ記述)→index.phpとするのがよさそうです。 index.phpは不具合後来た時に代用して、画面に表示しているpage.phpを修正するべきだと指摘があり確かにそのほうが良いなと感じました。 page.phpの表示以外はfunctions.phpにおいて機能させることでアップデートの修正がしやすいとのことなのでそちらで対応する予定です。 指摘を引用… index.phpに、通常投稿やらカスタム投稿やら固定ページやら全部の共通テンプレートを詰め込むと、グチャグチャになりません? パスから適当なテンプレートが推論されて、それが存在しないときは、index.phpが使われるので、それをトップにすると、ミスると必ずトップページを出す、なんか横柄な?サイトに見えるかも。 functions.phpなんていう汎用的なファイルを用意すべきではありませんね。 それはつまりどんどん肥大化していくことが予想されます。 ちゃんと、どういう振る舞いと状態があるのかを把握してクラス化することをおすすめします。 様々な制御を行った後にhtmlを直接出力しているようですが、情報を得ることと、それを望む形で出力することも分けるべきです。 RSS、投稿?、カテゴリ、ページ?というのが見えますが、それぞれは密に絡み合うものではないですよね。 役割をしっかり分けて、クラスごとに、特定の役割だけで終始完結するようにして、それを利用するようにしてhtmlを出力するようにしましょう。

php_learn
質問者

補足

はい。その認識で間違い無いです。 XAMPPで仮想環境を作りレンタルサーバーで実行しています。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.23

その説明書の書き方からすると、composer.jsonを配置すると、何かのタイミングでvendor以下のディレクトリが自動でインストールされるように感じます。 すでに配置したのにエラーが出ているのでしたら、自動インストールはされないようですね。 レンタルサーバー側でcomposerを使ったインストールの方法などありましたか。 私はvendor以下のディレクトリをFTPでアップロードすればいいと思うので、もしレンタルサーバー側でのインストール方法がないようでしたら、直接テーマディレクトリにアップロードしてみてください。この場合はcomposer.jsonは必要ないと思います。 いまさらですが、ローカル環境でテストしてみて、うまくいったらレンタルサーバーにアップロードされているのでしょうか。 それともPHPのコーディングからなにからレンタルサーバー上でやられているのでしょうか。

php_learn
質問者

お礼

すみません。レンタルボックスのターミナルで確認したところcomposeがインストールされているようなので、ファイルパスを調べてみます。

php_learn
質問者

補足

XAMPPを使いテストしながらレンタルサーバーカラフルボックスで実行しています。 どうやらカラフルボックスにはもともとcomposerは入っているようですが、ディレクトリを確認したところ表示されませんでした。 laravelを使用したことがないのでわからないのですが、autoload.phpとはどのような役割があり、どのように導入すればいいのでしょうか… cdnを使いファイルパスを通したことぐらいしかないので、調べても難しくて… お手数おかけしてすみません。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.22

すみません、補足のコードをよく見てませんでした。 回答No.19のことではなくて、データベースからの読み込み処理だったのですね。 いずれにしても、「autoload.php」には自作コードは書きません。 既存の必要なモジュールを自動的に読み込んでもらうためのものです。 自作コードは別のファイルに書いて、そこにこれも書いて、 require_once__DIR__.'/vendor/autoload.php'; 必要なモジュールを読み込ませる、と言う感じです。

php_learn
質問者

お礼

public_html/wp-includes/js/dist/vendorというファイルは見つけたのですが、autoload.phpが入っていないようです。 jsファイルのみが表示されております。

php_learn
質問者

補足

autoload.phpがレンタルサーバーにインストールされていない場合テーマディレクトリ直下に composer.json 置いて require_once __DIR__ . '/vendor/autoload.php';が必要と書いてあるんですが、composerでライブラリを使用して自作プラグインとして動作させるということでしょうか? そのまま記入した場合ファイルがないと表示されてしまいます。require_once(): Failed opening required こちらこそ説明不足で済みません。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.21

いえ、「autoload.php」は質問者さまが手書きで作成されたか、composerなどで自動生成されたかわかりませんが、このファイルには自作コードは書きません。 回答No.19のコードは、例えばファイル名「test.php」で新しく作っていただいて、実行してみていただき、私と同じような結果が表示されるかどうかを試していただきたかったのです。 ここでエラーや不具合があったら、それを先に直しておいた方が、あとで本体プログラムと結合しやすい、と言うか、部分ごとの動作確認ができるテストコードがあると、問題があった時に、他のコードの影響を受けているのかいないのかなどで原因箇所の切り分けがしやすいと私は思っているので、本番用の全体コードと、テスト用の部分コードで、私はよく開発しているのです。 説明が後回しになってしまい、迷わせたり、お手数をかけさせてすみません。

php_learn
質問者

お礼

あれから色々調べたのですがレンタル共有サーバーではcomposer installは使えないようです。 強引に使う方法もあるのですが、ルート権限のないレンタルサーバーで使用した場合セキュリティなどのリスクと思われます。 もし権限がないまま扱う場合xamppからvenderフォルダをコピーし、レンタルサーバのpublic_htmlに入れてパスを通すことで可能なようです。 「require './vendor/autoload.php';」 自動でファイルを読み込む方法はとれないのですが、手動でRSS部分を読み込んでもよいでしょうか?require_once(dirname(dirname(dirname(dirname( __FILE__ )))) . '/rss.php' ); //ファイル先頭でRSSを読み込む

php_learn
質問者

補足

回答を2つに分けてしまい申し訳ないのですが、参考サイトはこちらになります。 (WordPressに後からcomposerを入れる幾つかの方法) https://qiita.com/AknEp/items/c702f75c9d1bf03267a3

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.20

もしかしてこれまでのコードと結合されましたか。 動作確認のために、あのコードだけで実行してみてください。 サーバーの状況がわかりませんが、「index.php」でなくても、 テスト用に、適当なフォルダに適当なファイルを作成して、 それで実行してみてください。 それはそれとして。 もし結合されるのでしたら、 以前のRSSの処理は全部なくしてから試してみてください。 require_once __DIR__.'/vendor/autoload.php'; これはどこかで一回実行されればいいので、 今回の方からなくして大丈夫だと思います。 もし、以前のコードを残したまま、結合したいのでしたら、 今回の関数名を「get_rss_feed2」とかに変更してみてください。

php_learn
質問者

お礼

こんなにfunctionsは必要ないと思うのですが、括ってみました。 function one_page_count($post_items)の部分ですが、これでいいのかわかりません… ※別ファイルに分けるphp <?php //別ファイルにして読み込む場合 function db($hlxclitx_wp1){//DB名を引数として受け取る $dbname //DB接続 try { $pdo = new PDO(“mysql:dbname=”$hlxclitx_wp1”_name;host=”localhost”;charset=utf8″,”hlxclitx_wp1”,”E.HrypHWxNmltXgC5eS26”)); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $pdo; }catch (PDOException $e) { echo $e->getMessage(); return $db = null; } } // カテゴリーIDをキーにしたカテゴリー配列を生成 function get_category_name_by_id($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); } //古いデータを削除 //※先に実行する //ものがないものはfunctons.phpに書いても使えないので、require_onceでまとめて読み込む認識 function delete_date_pdo($delete_date) { $sql = 'DELETE FROM rss_feed WHERE date < ?'; $stmt = $dbh->prepare($sql); $delete_date = date('Y-m-d H:i:s', strtotime('-1 week')); //※削除対象日付 $stmt->execute([$delete_date]); } //RSS保存 function save_url_rss($stmt){//本来は値がほしいところでfunction{}するのだろう長さの加減がわからず $url1 = [ 'http://nns2ch.net/index.rdf', 'http://aqua2ch.net/index.rdf', 'https://worldfn.net/index.rdf', ]; $stmt = $dbh->prepare('insert into rss_feed (title, link, date, img) values (?, ?, ?, ?) on duplicate key update title=?, link=?, date=?, img=?'); 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)); //※削除対象日付より古いRSSは保存しない 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]); } } } function one_page_count($post_items){ //表示設定 $current_page = $_REQUEST['page'] ?? 1; //現在ページ $block_per_page = 2; //ページあたりブロック件数 $rss_per_block = 18; //ブロックあたりRSS件数 $posts_per_block = 5; //ブロックあたり投稿件数 //RSS読み込み $rss_per_page = $block_per_page * $rss_per_block; //ページあたりRSS件数 $rss_offset = ($current_page - 1) * $rss_per_page; //RSSオフセット $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); } ?>

php_learn
質問者

補足

質問があるのですが、以下のコードをautoload.phpで保存して、require_once__DIR__.'/vendor/autoload.php';を使い読み込むという認識であってますでしょうか? //autoload.phpで保存 <?php $hoge = 1; ?> <div class="img-wrap2"> 以下略 $sql = "select name, title, url, created from matome"; foreach ($db->query($sql) as $row) { echo $row["name"]."\n"; //タイトル echo $row["title"]."\n"; //記事 echo $row["url"]."\n"; //記事 echo $row["created"]."\n"; //投稿時刻 echo "<br>"; } ?>

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

サンプルを作成してみました。 RSSのURLは省略しましたので、既出のものを入れてください。 既出のURLでは件数が十分でないため、全体に渡っては表示されませんでした。 コードの各処理の解説は割愛しましたので、不明点があれば聞いてください。 なお、最下部の処理はループにしていませんが、本体の処理と結合した際には、ブロックインデックスの変数を持っておいて、本体ループの中で「display_rss(変数);」のようになります。 <?php date_default_timezone_set('Asia/Tokyo'); require_once __DIR__.'/vendor/autoload.php'; function get_rss_feed() { global $feed_items; $feed_items = []; $url1 = [ '', '', '', ]; foreach ($url1 as $url) { $feed = new SimplePie(); $feed->set_feed_url($url); $feed->enable_cache(false); $success = $feed->init(); if (false === $success) { $error_msg = $feed->error(); break; } $feed->handle_content_type(); $feeds[] = $feed; } if ($success) { foreach ($feeds as $feed_idx => $feed) { foreach ($feed->get_items() as $item) { $feed_items[$feed_idx][] = $item; } } } else { echo $error_msg; } } function display_rss($block_idx) { global $feed_items; for ($feed_idx = 0; $feed_idx < 3; ++$feed_idx) { echo '<div class="rss_block_style">'; for ($i = 0; $i < 4; ++$i) { $idx = $block_idx * 4 + $i; if ($idx >= count($feed_items[$feed_idx])) { break; } $item = $feed_items[$feed_idx][$idx]; echo '<div class="rss_item_style">'; echo $item->get_feed()->get_title().'<br>'; echo '<a href="'.$item->get_link().'">'.$item->get_title().'</a><br>'; echo $item->get_date('Y-m-d h:i:s'); echo '</div>'; } echo '</div>'; } } ?> <style> .rss_block_style { display: flex; } .rss_item_style { width: 200px; overflow-wrap: normal; } </style> <?php get_rss_feed(); echo '<div><h2>本体1</h2></div>'; display_rss(0); echo '<div><h2>本体2</h2></div>'; display_rss(1); echo '<div><h2>本体3</h2></div>'; display_rss(2); echo '<div><h2>本体4</h2></div>'; display_rss(3); echo '<div><h2>本体5</h2></div>';

php_learn
質問者

お礼

functions.phpの勝手がよくわかっていませんので、以下の文をfunctions.phpに配置したときに表示部分が問題なく動くか心配です。 function one_page_count($post_items){ //表示設定 $current_page = $_REQUEST['page'] ?? 1; //現在ページ $block_per_page = 2; //ページあたりブロック件数 $rss_per_block = 18; //ブロックあたりRSS件数 $posts_per_block = 5; //ブロックあたり投稿件数 //RSS読み込み $rss_per_page = $block_per_page * $rss_per_block; //ページあたりRSS件数 $rss_offset = ($current_page - 1) * $rss_per_page; //RSSオフセット $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); } ※表示部分(page.php) <?php require_once(“読み込みファイル.php“); //DB接続情報の読み込み //表示 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>"; //※画像URLがあれば表示 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]; // 投稿の情報を追加 set_other_data($item); ?> <!-- タイトル --> <div><span class="img-wrap"><?php echo $item->post_title; ?></span></div> <!-- アイキャッチ --> <div><span class="img-wrap"><img src="<?php echo $item->thumbnail; ?>"></span></div> <!-- 日付 --> <div class="post-meta2"> <div class="img-wrap3"><?php echo $item->post_date; ?> </div> </div> <?php // カテゴリー if ($item->categories) { echo '<ul>'; foreach ($item->categories as $cat_ID) { $category = $categories[$cat_ID]; echo '<li class="cat1"'.$category->slug.'"><a href="'.esc_url(get_category_link($cat_ID)).'">'.$category->cat_name.'</a></li>'; } echo '</ul>'; } ?> <!-- コメント --> <div><span class="singlecomments"><a href="<?php echo $item->comments_link; ?>"><?php echo $item->comments; ?></a></span></div> <!-- 記事の抜粋 --> <div class="img-wrap4"><?php echo $item->post_excerpt; ?> </div> <!-- 続きを読む --> <div class="img-wrap5"><a href="<?php echo $item->guid; ?>">続きを読む</a></div> <?php } } //ページリンク表示 $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
質問者

補足

コードを考えていただきありがとうございます。 5段落ごとに表示するため<?php function get_rss_feed(){ ?> <?php } ?>で教えていただいたコードを囲んでいるのですが、 Cannot redeclare get_rss_feed()と表示され同じ関数を使えないと指摘が入ってしまいます。 <?php date_default_timezone_set('Asia/Tokyo'); require_once(dirname(dirname(dirname(dirname( __FILE__ )))) . '/wp-load.php' ); //ファイル先頭でwp-load.phpを読み込む function get_rss_feed()の部分 関数に名前を付ける方法をとろうと思ったのですが後の処理につなげる方法が難しくできませんでした。 第2に以下の部分を別のphpファイルにしてrequire_onceで再度読み込ませる方法を考えたのですが、可能であればファイルを読み込ませるのは避けたいです。 同一ファイル内のfunction2重定義回避を行うにはどのような方法をとればいいのでしょうか? function get_rss_feed() { global $feed_items; $feed_items = []; $url1 = [ 'http://i2chmeijin.blog.fc2.com/', 'http://www.akb48matomemory.com/index.rdf', 'http://blog.livedoor.jp/aquarium_matome/index.rdf', ]; foreach ($url1 as $url) { $feed = new SimplePie(); $feed->set_feed_url($url); $feed->enable_cache(false); $success = $feed->init(); if (false === $success) { $error_msg = $feed->error(); break; } $feed->handle_content_type(); $feeds[] = $feed; } if ($success) { foreach ($feeds as $feed_idx => $feed) { foreach ($feed->get_items() as $item) { $feed_items[$feed_idx][] = $item; } } } else { echo $error_msg; } }

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

説明不足ですみません。 「②display_rss」はそう言う機能を持った関数を自作する際の、仮に付けた関数名です。 それと、私の方ではDB保存はしない方向で考えています。

php_learn
質問者

補足

DB保存は勉強目的で頑張ってみます。 オリジナルの関数なんですね、失礼いたしました。

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

そうですね。 このままget_rss_feedを呼ぶとリセットされるので同じものが表示されてしまいます。 複数のサイトからRSSを取得するとして、表示する際の決め事はありますか。 例えば、4件(同じサイトから4件)×3(3つのサイト)とかです。 それと、12個取得と言っても、取得できるものが12個未満の場合もあると思いますので、その時はどうするかも考える必要があるかも知れません。 1ブロックとは、本体の「3記事×5行」ごとに入るRSSのかたまりのことでよかったでしょうか。 また、1プロックにRSSを12件表示する、で合っていますか。 つまり1ページの内容がこんな感じ。 本体の記事15件 RSS12件 本体の記事15件 RSS12件 本体の記事15件 RSS12件 本体の記事15件 RSS12件 本体の記事15件 RSSの流れとしては、こんな方法が考えられます。 ①get_rss_feed 同じものが表示されないために、取得する処理は1回にして、表示したい情報を1ページ分ためておくための関数。 上記のページ構成で合っていれば、RSSは48件分ためます。 ②display_rss 表示したいところで表示したい件数分を表示するための関数。 1回で12件分表示するようにして、 引数で表示するブロック番号を渡す。 サンプルコードを考えてみるので、改めて投稿させてください。

php_learn
質問者

補足

決め事としましてはおっしゃる通り4件(同じサイトから4件)×3(3つのサイト)が理想ですね。 12個未満の場合というのはキャッシュの関係でしょうか? 本体の記事15件 RSS4件 本体の記事15件 RSS4件 本体の記事15件 RSS4件 本体の記事15件 RSS4件 本体の記事15件 が理想ですかね、場合によっては6件にして2件ずつ横並びの3段にするかもしれませんが。 12件ずつですと記事が埋もれる可能性が考えられますので。 なるほど、記事をためておいて分けて取り出すことも可能なのですね。勉強になりました。 ②display_rssについて知らなかったのですが、Simple pieのパラメーターに記述があるのでしょうか? エラー原因は$dbh = new PDO($dsn,$user,$pass);にあったようで$passwardにすると治ったのですが、 $stmt = $db->prepare($sql);でエラーが出ておりsyntax error, unexpected ' ' (T_STRING) $dbh = new PDO($dsn,$user,$pass); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) 変数名がdbとdbhで違うので修正してみたんですが、違うようです。もう少し調べてみます。 今回教えていただいた、display_rssを使用してコードを自分なりに組んでみます。 解説付きで教えていただきありがとうございます。

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

同時に複数人から閲覧されることがありますか。 色々考えていたのですが、DB保存には少し問題があるような気がしてきました。 ページが表示される時に一回だけ、とは言ったのですが、同時に複数人から閲覧されると、それぞれのタイミングでDB保存を実行してしまいます。 RSSの取得から合わせるとそれなりに負荷がかかりますし、ほぼ同じタイミングで取得したRSSはほとんど同じ記事になりそうなので、それを保存する必要はなかったりします。 同じ記事をどうするかは色々な方法があるのですが、DB保存にこだわらないのでしたら、SimplePieが便利にできているので、RSSを取得しておいてから、表示したいところで表示したい分だけ表示する、こともできそうなので、DB保存するか否かを検討してみてください。

php_learn
質問者

お礼

一つお聞きしたいのですが、RSSをSimplepieを使って必要な分だけ表示する場合、5段落ごとに表示するとして、1ブロック4件×3の12個表示する場合 $get_count = 12; // 取得する回数(仮コード) で12個まとめて取得した場合 <?php function get_rss_feed(){ ?> <?php } ?> でRSSをループさせるとリセットがかかって12件それぞれ同じものが表示されるのでしょうか? 同じものが表示されないための場合の対策としてifで分岐させて、RSSに番号をふりブロックする方法しか思い浮かばないのですが…

php_learn
質問者

補足

RSSについてまだ理解が浅いのですが、キャッシュを使って一定のタイミングでデータを消去するのはどうでしょうか? RSSを習得してきたタイミングでデータ保存されると思っていたのですが… <?php require_once(dirname(dirname(dirname(dirname( __FILE__ )))) . '/wp-load.php' ); //ファイルの先頭で読み込む try { $dsn = 'mysql:dbname=ozvutmpq_wp1;host=localhost'; $user = 'ozvutmpq_wp1'; $password = 'Rn_&Zi$gWKae'; $dbh = new PDO($dsn,$user,$pass); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);//エラーが発生した時に、例外を投げる echo "データベースへの接続が出来ました"; }catch (PDOException $e) { echo $e->getMessage();// err時はメッセージを表示 exit; } date_default_timezone_set("Asia/Tokyo"); $url1 = [ 'http://', 'http://', 'http://',];//フィード登録1次元配列に foreach ($url1 as $url) { //複数のRSSを結合 $feed=new SimplePie; // インスタンス生成 $feed->set_feed_url($url);// フィードしたいRSSのURL $feed->enable_cache(false); // キャッシュによって遅延が発生 デフォルトでは12時間 $success = $feed->init();// RSSが取得できたら情報を解析する if ( $success === false ){ // feedでエラーになったら終了 $error_msg = $feed->error();// メッセージ break; } $feed->handle_content_type();//コンテンツまたは空白が既にブラウザーに送信されている場合は機能しません $feeds[] = $feed; } // RSSが取得できたら情報をパースする if ($success){ $get_count = 12; // 取得数 $sql = "insert IGNORE into matome (name, title, url, created) values (:name,:title,:url,:created)"; // foreach内で代入するのは無駄なのでここで定義 // 各feed毎にget_itemsを繰り返す foreach ($feeds as $feed) { // get_itemsの引数を指定して何個取得するか指定 foreach ($feed->get_items(0, $get_count) as $item) { $name = $item->get_feed()->get_title(); $title = $item->get_title(); $url = $item->get_link(); $date = $item->get_date('Y-m-d h:i:s'); $stmt = $db->prepare($sql); $stmt->execute([ ':name' => $name, ':title' => $title, ':url' => $url, ':created' => $date ]); } } } else { echo error_msg; } $sql = "select name, title, url, created from matome"; foreach ($db->query($sql) as $row) { echo $row["name"]."\n"; //タイトル echo $row["title"]."\n"; //記事 echo $row["url"]."\n"; //記事 echo $row["created"]."\n"; //投稿時刻 echo "<br>"; } ?> 教えていただいたコードと組み合わせてみたのですが、using password: NOと表示されてしまい試行錯誤しております。MySQL database passwordを入れてるんですが… コードを保存せずにRSSを表示するコードも考えてみます。

関連するQ&A