【PHP】XML_RSSで未来の記事を無視(スキップ)する方法【PEAR】

ブログやニュースサイトなどで配信されるRSSフィードを利用すると、オリジナルのRSSリーダーを作ることができます。

ただ、ブログなどでは、未来の日時を利用した記事が常に最上位に表示されていることもあります。

こうしたブログのRSSフィードを利用すると、その未来の記事が常に最上位に来てしまい不都合が生じます。

そこで、未来の記事を無視(スキップ)する処理が必要になります。この点、ネットで探したのですが見つからなかったので簡単なスクリプトを書いてみました。

ちなみにベースとなるRSSの処理は、PEARのXML_RSSです。

また、ベースとなるスクリプトは、レッツPHP!さんのスクリプトを利用させて頂いてます。

<?php
//PEAR導入済みの場合↓
require "XML/RSS.php";

// RSSサイトURL(複数可)
$rdf[] = "http://rss.asahi.com/f/asahi_newsheadlines";#朝日
$rdf[] = "http://rss.yomiuri.co.jp/rss/yol/topstories";#読売
$rdf[] = "http://mainichi.pheedo.jp/f/mainichijp_flash";#毎日
$rdf[] = "http://sankei.jp.msn.com/rss/news/points.xml";#産経

// 記事表示件数
$num = 4;

// 出力文字コード
$enc = "UTF-8";
// 日付ソート関数
function cmp ($a, $b) {
  $a = (isset($a['items'][0]['pubdate'])) ?
strtotime($a['items'][0]['pubdate']) :
strtotime(str_replace("T", " ", substr($a['items'][0]['dc:date'], 0, 19)));

    $b = (isset($b['items'][0]['pubdate'])) ?
strtotime($b['items'][0]['pubdate']) :
strtotime(str_replace("T", " ", substr($b['items'][0]['dc:date'], 0, 19)));

if ($a == $b) return 0;
    return ($a > $b) ? -1 : 1;
}
// RSS取得・解析
foreach ($rdf as $k=>$rssurl) {
    $r =& new XML_RSS($rssurl);
    if (PEAR::isError($r)) continue;
    $r->parse();
    if ($r->getChannelInfo()) $ch[$k] = $r->getChannelInfo();
    $ch[$k]['items'] = $r->getItems();
}
/**** 未来の記事を無視する処理start ****/ //現在時刻取得 
$nowtime = time();
for ($i=0; $i < $num; $i++) {
    // 記事更新時間取得
    $time = (isset($ch[$i]['items'][0]['pubdate'])) ?
    strtotime($ch[$i]['items'][0]['pubdate']) :
     strtotime(str_replace("T", " ", substr($ch[$i]['items'][0]['dc:date'], 0, 19)));

 //更新時間が未来の日時ならばその配列を削除

  if ($time > $nowtime) {
     array_shift($ch[$i]['items']);
  }
}
/******** 処理end ********/
usort($ch, "cmp");

上記処理でやっていることは単純です。

記事の更新時間を取得して、それが未来の日時ならば、その配列を削除するだけです。

もし、未来の記事が2つあるならば下のようにします。

/******** 未来の記事を2つスキップする処理 ********/
$nowtime = time();
for ($i=0; $i<$num; $i++) {    
// 記事更新時間
$time = (isset($ch[$i]['items'][0]['pubdate'])) ?
strtotime($ch[$i]['items'][0]['pubdate']) :
strtotime(str_replace("T", " ", substr($ch[$i]['items'][0]['dc:date'], 0, 19)));
  if ($time > $nowtime) {
    array_shift($ch[$i]['items']);
 //未来の記事2つ用     $time = (isset($ch[$i]['items'][0]['pubdate'])) ?
    strtotime($ch[$i]['items'][0]['pubdate']) :
    strtotime(str_replace("T", " ", substr($ch[$i]['items'][0]['dc:date'], 0, 19)));
 //もう一度、配列を削除する     if ($time > $nowtime) {
        array_shift($ch[$i]['items']);
    }
  }
}

これもやっていることは単純です。一つ目で未来の記事だった場合に、配列を一つ削除しますが、更に、二つ目の記事の日時をチェックして、それが未来だった場合には、その配列をも削除するという処理です。if文の入れ子になっています。

ちなみに、この部分を応用して再帰関数化すれば、未来の記事が10個でも20個でもシンプルなスクリプトで処理できるようになります。

カテゴリー: PHP パーマリンク

コメントを残す

メールアドレスが公開されることはありません。