WordPressで複数外部RSSフィードを取得し、統合して更新日時順に表示する

サイト構成

root/
 ├ aaa
 ├ bbb
 ├ ccc
 ├ ddd
 └ eee

AAA〜EEEの投稿を、サイト関係なく新着順でrootサイトに出したい。という要望に対応しましたので備忘録として。
※AAA〜EEEのサイトは全てWordPressです。

要は、別サイトの複数のRSSを取得してきて、一つに統合の後、更新日時順で指定箇所に出したい ということです。

こちらを参考に、出力時意図したHTML構造になるよう改造しました
複数のRSSに並列リクエスト後マージして返す関数

rootのfunction.php

/** 複数RSS取得と出力 **/
function fetch_rss_items(array $urls) {
	/* 0. 配列の初期化 */
	$items = array();
	if(!$urls) {
		return $items;
	}

	/* 1. cURLリソースの準備 */
	$mh = curl_multi_init();
	foreach($urls as $url) {
		$ch = curl_init();
		curl_setopt_array($ch, array(
			CURLOPT_URL => filter_var($url),
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_TIMEOUT => 5,
			CURLOPT_CONNECTTIMEOUT => 5,
			CURLOPT_ENCODING => 'gzip',
		));
		curl_multi_add_handle($mh, $ch);
	}

	/* 2. リクエストの開始 */
	while(curl_multi_exec($mh, $running) === CURLM_CALL_MULTI_PERFORM);

	/* 3. レスポンスの待機 */
	do switch (curl_multi_select($mh, 5)) {
		case -1: /* 失敗 */
			usleep(10);
			while(curl_multi_exec($mh, $running) === CURLM_CALL_MULTI_PERFORM);

		case 0: /* タイムアウト */
			continue 2;

		default: /* どれかが読み取り可能な状態になった */
			while(curl_multi_exec($mh, $running) === CURLM_CALL_MULTI_PERFORM);
			do if($info = curl_multi_info_read($mh, $remains)) {
				$xml = curl_multi_getcontent($info['handle']);
				curl_multi_remove_handle($mh, $info['handle']);
				if(!$xml = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) { continue; }
				foreach($xml->channel->item as $item) {
					/* NEWアイコン */
					$today = date_i18n('U');
					$entry = strtotime((string)$item->pubDate);
					$kiji = date('U',($today - $entry)) / 86400 ;
					if(6 > $kiji) { $new = '<span class="new">new</span>'; }
					else { $new = ''; }

					/* 一番最初の画像取得 */
					if(preg_match_all('/<img(.+?)>/is', (string)$item->description, $matches)){
						foreach($matches[0] as $img){
							if(preg_match('/src=[\'"](.+?(jpe?g|png))[\'"]/', $img, $m)){
								$item->thumbnail = $m[1];
							}
						}
					}

					/* サイト名取得 */
					if(preg_match("/aaa/",(string)$item->link)){ $site = 'AAA'; }
					elseif(preg_match("/bbb/",(string)$item->link)){ $site = 'BBB'; }
					elseif(preg_match("/ccc/",(string)$item->link)){ $site = 'CCC'; }
					elseif(preg_match("/ddd/",(string)$item->link)){ $site = 'DDD'; }
					elseif(preg_match("/eee/",(string)$item->link)){ $site = 'EEE'; }
					else {$site = 'ブログ';}

					/* 配列にセット */
					$items[] = array(
						'site' => $site,
						'date' => date("Y.m.d", strtotime($item->pubDate)),
						'title' => (string)$item->title,
						'link'  => (string)$item->link,
						'thumbnail' => (string)$item->thumbnail,
						'timestamp' => strtotime((string)$item->pubDate),
						'new' => $new
					);
				}
			} while($remains);
	} while($running);

	/* 4. タイムスタンプが新しい順にソート */
	usort($items, function ($a, $b) {
		return $b['timestamp'] - $a['timestamp'];
	});

	/* 5. 配列をHTMLに整えて返す */
	print '<ul>';
	print '<li><a href="'.$items[0]['link'].'"><div class="photoarea"><img src="'.$items[0]['thumbnail'].'" alt="" /></div><div class="textarea"><span class="data">'.$items[0]['date'].'</span><span class="cat">'.$items[0]['site'].'</span><br>'.$items[0]['title'].$items[0]['new'].'</div></a></li>';
	print '<li><a href="'.$items[1]['link'].'"><div class="photoarea"><img src="'.$items[1]['thumbnail'].'" alt="" /></div><div class="textarea"><span class="data">'.$items[1]['date'].'</span><span class="cat">'.$items[1]['site'].'</span><br>'.$items[1]['title'].$items[1]['new'].'</div></a></li>';
	print '<li><a href="'.$items[2]['link'].'"><div class="photoarea"><img src="'.$items[2]['thumbnail'].'" alt="" /></div><div class="textarea"><span class="data">'.$items[2]['date'].'</span><span class="cat">'.$items[2]['site'].'</span><br>'.$items[2]['title'].$items[2]['new'].'</div></a></li>';
	print '</ul>';
}

rootのindex.phpなど出力したい場所に

print_r(fetch_rss_items(array(
	'https://www.sendai-kuraso.com/aaa/feed',
	'https://www.sendai-kuraso.com/bbb/feed',
	'https://www.sendai-kuraso.com/ccc/feed',
	'https://www.sendai-kuraso.com/ddd/feed',
	'https://www.sendai-kuraso.com/eee/feed'
)));

書いた人:やまライダー(嫁)

Web屋さんで8時間フルタイム勤務をしている、いわゆるワーキングマザー。
夫婦共働きで、ムスメ氏を育てています。
主に資産運用にかかわるお金の話、ムスメ氏を育てていく上での子育ての話、そしてたまにお仕事関連の記事を書いていく予定。
プロフィールを見る