🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

PHPで複数サイトのRSSをfavicon付きで取得する

PHPで複数のサイトからRSSfavicon付きで取得して、リストにする方法です。

PHPの関数でもできるらしいですが、各サイトのそれぞれの形式に対応するとか、文字コードとかなんやらかんやら面倒やったので、
Magpie RSShttp://magpierss.sourceforge.net/ を利用しました。

ソース

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta type charset="UTF-8"/>
<title>RSS Feeds Frame</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<?php
require_once('magpierss/rss_fetch.inc');  //MagpieRSSロード
define('MAGPIE_OUTPUT_ENCODING','UTF-8');
//読み込むRSSを配列に格納
$rssUrl=array(
	"http://nyanyanyanya.jp/feed",
	"http://piyopiyopiyo.com/rss.xml"
);

//表示する記事の"総"件数
$num=20;
$HTMLbody ="";
if($datacount !== 0){

	foreach ($rssUrl as $no => $rss_url) {
		if ($rss_url != '') {
			//URLからRSSを取得
			$rss = @fetch_rss($rss_url);
			$rss->items = array_slice($rss->items, 0, 1);// 後ろの数字が各RSSから取得する記事数
			if ($rss != NULL) {
				for ($i=0; $i<count($rss->items); $i++) {
					//サイトのタイトルをitemsに格納
					$rss->items[$i]["site_title"] = $rss->channel["title"];
					$rss->items[$i]["site_link"] = $rss->channel["link"];
				}
				//itemsだけ別配列に格納
				$rssItemsArray[] = $rss->items;
			}
		}
	}

	$concatArray = array();
	if (is_array($rssItemsArray)) {
		for($i=0;$i<count($rssItemsArray);$i++){
			//配列を統合する
			$concatArray = array_merge($concatArray,$rssItemsArray[$i]);
		}
		foreach ($concatArray as $no => $values) {

			//「RSS広告は除外する」
			if(preg_match("/PR:/", $values["title"])){
			}else{
				$title=$values["title"];
				$link=$values["link"];
				$site_link=$values["site_link"];
				//記事ごとに必要な項目を抽出
				$rssArray[]=array($title, $link, $site_link);
			}
		}

		//配列をユーザー定義関数でソート
		if ($rssArray) { usort($rssArray, 'cmp'); }
		if (count($rssArray) > $num) {
			$count=$num;
		} else {
			$count=count($rssArray);
		}
		//必要な件数分だけHTML整形
		$HTMLbody ="<ul id=\"feed_body\">";
		for ($i=0; $i<$count; $i++) {
			$title=$rssArray[$i][0];
			$link=$rssArray[$i][1];
			$site_link=$rssArray[$i][2];
			$favicon="<img src=\"http://favicon.hatena.ne.jp/?url=".$site_link."\" />";
			$HTMLbody .="<li class=\"feed_list\">"
				.$favicon.
				"<span class=\"entry_title\">
				  			<a href=\"".$link."\" target=\"_blank\">".$title."</a>
			  		</span>
			</li>";
		}
		$HTMLbody .="</ul>";
	}
}else{
	$HTMLbody .="まだ記事がありません。";
}

//=======================================================
// 多次元配列ソート用比較関数
// この場合は配列の1番目の項目を降順にソート
//=======================================================
function cmp($a, $b) {
	if ($a[0] == $b[0]) return 0;
	return ($a[0] > $b[0]) ? -1 : 1;
}
?>
<?php echo $HTMLbody ?>
</body>
</html>

基本的には、

参考:複数のRSSを統合して更新日時でソートする方法[PHP] | DEZIMO.COM - FireworksやWEBのことなど -

こちらのものを転用しています。
ありがとうございます!

変更箇所

  1. 各サイトからの記事数を制御できるようにしました。
  2. faviconを表示させてます。
  3. 最終的に出力するHTMLの記述をひとつのul内に収めました。

各サイトからの記事数を制御する。

$rss->items = array_slice($rss->items, 0, 1);// 後ろの数字が各RSSから取得する記事数
//$rss->items = array_slice($rss->items, 0, 4);// 4件取得します。
//$rss->items = array_slice($rss->items, 0, 10);// 10件取得します。

後ろの数字を変えることで、読み込み件数を制御できます。

faviconを表示する。

Magpie RSSのパラメータ?として、各サイトのフィードから取得するitemsという配列ですが、中身がこうなってます。

array(
	title => 'Weekly Peace Vigil',
	link => 'http://protest.net/NorthEast/calendrome.cgi?span=event&ID=210257',
	description => 'Wear a white ribbon',
	dc => array (
			subject => 'Peace'
		),
	ev => array (
		startdate => '2002-06-01T11:00:00',
		enddate => '2002-06-01T12:00:00',
		type => 'Protest',
		location => 'Northampton, MA'
	)
);

最初にchannelなる単位でサイトを取得して、そのサイト単位でitemsなる配列にデータを格納してるみたいです。

ということで、faviconが入ってなーい!
フィードの一覧なので、favicon無しはさみしい・・。

てなわけで。

参考:リンク先のFaviconを取得・表示できるWebサービス(API)とJavaScript・プラグインまとめ : web memo.Ver.2

こちらから、はてなの非公式?faviconサービスAPIを。

$favicon="<img src=\"http://favicon.hatena.ne.jp/?url=".$site_link."\" />";
http://favicon.hatena.ne.jp/?url=[取得したいサイトのURL]

これを、imgタグのソースに指定します。

faviconが取得できなかったときに、デフォルト画像を返してくれるところも素晴らしいー!

最終的なHTMLをulタグに収める。

これは割愛。
最後のfor文の外に出すだけ。

おわりに

Magpie RSSの設置方法などは、色々なところで記事があるので書いてません。
いやー便利な世の中だわ。