utility
複数サイトのfeedをひとまとめにする
作成日: 2024年6月16日
滅多に使わないだろうが、複数サイトのFeedをひとまとめにするphp。
実際用いたのはFacebookPAGEへの自動投稿をIFTTTで行っていたが、無料版のIFTTTではアップレットが2つまでしか使えないので管理を簡易にするためにFeedをひとまとめにしてアップレット一つで自動投稿するものを考えた。
<?php
// ヘッダーを設定してRSSフィードであることをブラウザに伝える
header('Content-Type: application/rss+xml; charset=utf-8');
// RSSフィードの開始タグを出力
echo '<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>' . PHP_EOL;
// 開始タグを出力
echo '<channel>' . PHP_EOL;
// feed title等を手入力、スクレイピングよか早いので初期直書き
echo '<title>YOUR_TITLE</title>' . PHP_EOL;
echo '<link>https://表示したいURL.com</link>' . PHP_EOL;
echo '<description>サイトの説明</description>' . PHP_EOL;
echo '<atom:link href="https://RSSファイルのパスrss.php" rel="self" type="application/rss+xml" />' . PHP_EOL;
echo '<language>ja</language>' . PHP_EOL;
function fetch_feed($url) {
$rss = simplexml_load_file($url);
return $rss;
}
function combine_feeds($feed_urls) {
$combined_entries = [];
foreach ($feed_urls as $feed_url) {
$feed = fetch_feed($feed_url);
foreach ($feed->channel->item as $item) {
$combined_entries[] = $item;
}
}
// 日付でソート
usort($combined_entries, function($a, $b) {
return strtotime($b->pubDate) - strtotime($a->pubDate);
});
return $combined_entries;
}
// 取得したいRSSフィードのURLを配列に指定
$feed_urls = array(
'https://サイト1URL/feed',
'https://サイト2URL/feed',
'https://サイト3URL/feed',
'https://サイト4URL/feed',
// 他のRSSフィードのURLも追加可能
);
$combined_entries = combine_feeds($feed_urls);
// 各エントリーの情報を表示
foreach ($combined_entries as $entry) {
echo '<item>' . PHP_EOL;
echo "<title>{$entry->title}</title>" . PHP_EOL;
echo "<pubDate>{$entry->pubDate}</pubDate>" . PHP_EOL;
echo "<link>{$entry->link}</link>" . PHP_EOL;
echo "<guid>{$entry->guid}</guid>" . PHP_EOL;
// descriptionを100文字に制限してCDATAセクションで囲む
$description = $entry->description;
if (strlen($description) > 100) {
$description = mb_substr($description, 0, 100) . '...'; // 100文字に制限し、続きがあることを示す
}
echo "<description><![CDATA[{$description}]]></description>" . PHP_EOL;
// content:encodedを取得し、iframeおよびscriptタグを削除
$content_encoded = $entry->children('content', true)->encoded;
$content_encoded = preg_replace(array('/<iframe.*?<\/iframe>/is', '/<p><script.*?<\/script>/is', '/<script.*?<\/script>/is'), '', $content_encoded);//ここは出力される内容からエラーになる部分を削除、任意で変える
echo "<content:encoded><![CDATA[{$content_encoded}]]></content:encoded>" . PHP_EOL;
echo '</item>' . PHP_EOL;
}
// フィードの終了タグを出力
echo '</channel>' . PHP_EOL;
echo '</rss>' . PHP_EOL;
?>
これを任意にディレクトリに置けばOK。
WPの場合は今更だがautoPとかでエラーになる場合があるから注意。validatorでのチェックをお忘れなく。
それとたまにIFTTTのactivityを確認して稼働状態もチェックするのがベター。