Webコンテンツを配信するためのXML文書フォーマットであるRSSやAtomの情報(フィード)を取得して、自分のサイト内に表示する場合に使うPHPスクリプトについて紹介します。
RSSとAtomでは、XMLの構造が異なるため条件分岐が必要になります。また、同じRSSでも、RSS 2.0 と RSS 1.0 では書式が異なるため、これらの判定にも条件分岐が必要となります。
今回紹介するPHPスクリプトは、RSS2.0、RSS1.0、Atomの3つを判別して、どのフィードを受け取っても正しく出力できるようにしています。
以下は、北海道大学のRSS「お知らせ/プレスリリース/研究発表」を取得するPHPスクリプトと、取得した情報を表示するHTMLソースです。PHPの関数 simplexml_load_file の引数に、取得したいRSSやAtomのURLを指定します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>RSSを取得してページに表示する</title>
</head>
<body>
<?php
$rss = simplexml_load_file('http://www.hokudai.ac.jp/news/index.xml');
// Atom であることを表すフラグ
$isAtom = false;
// RSS 1.0 であることを表すフラグ
$isRSS1 = false;
// RSS 2.0 と仮定して、ひとつのトピックについての情報を取得
$single = $rss->channel->item;
if (empty($single)) {
// 失敗したら Atom とみなして、ひとつのトピックについての情報を取得
$isAtom = true;
$single = $rss->entry;
}
if (empty($single)) {
// 失敗したら RSS 1.0 とみなして、ひとつのトピックについての情報を取得
$isRSS1 = true;
$single = $rss;
}
foreach ($single as $info) {
// 各投稿の情報を取り出す
$title = $info->title;
if ($isRSS1) {
// RSS 1.0
$link = $info->link;
$dc_date = $info->children('http://purl.org/dc/elements/1.1/');
$date = date('Y/m/d', strtotime($dc_date->date));
$description = $info->description;
} else if ($isAtom) {
// Atom
$link = $info->link['href'];
$date = date("Y/m/d", strtotime($info->updated));
$description = $info->content;
} else {
// RSS 2.0
$link = $info->link;
$date = date("Y/m/d", strtotime($info->pubDate));
$description = $info->description;
}
?>
<div class="singleRelease">
<time class="date"><?php echo $date; ?></time> : <a href="<?php echo $link; ?>" target="_blank"><?php echo $title; ?></a>
<!-- タイトルのみの一覧を表示する場合は下の1行を削除 -->
<div><?php echo $description; ?></div>
</div>
<?php
}
?>
</body>
</html>
ブラウザで表示すると、以下のような結果になります。
見出しのみを取得した場合は、以下のようになります。
RSSやAtomを取得するスクリプトについて
RSS 2.0 では、RSSのXML構造は以下のようになっています。赤線で囲んでいる部分(itemタグに囲まれた部分)が、ひとつのトピックです。全てのトピックはchannelタグで囲まれています。
したがって、$rss->channel->item はchannelタグの中のitemタグ(ひとつのトピック)を指します。その中に含まれる投稿日時やタイトルなどの情報を取得し、それぞれ適切なタグで表示しています。
この処理を、foreach によってトピックの数だけ繰り返し処理することで、全てのトピックについて取得して表示できます。
RSS2.0 ではなく Atom によるXMLの場合は以下のように、ひとつのトピックを表すタグが item ではなく entry となっています。また、entry の中にある時間や説明、リンク先なども別のタグになっています。
(画像は奈良先端科学技術大学院大学のプレスリリースのAtom)
RSS 1.0 の場合は、最も外側を囲むタグ rdf:RDF の直下に、直接個々のトピックを表す item が存在する構造になっています。
(画像は科学技術振興機構のプレスリリースのRSS1.0)
対象となるXMLがAtomであった場合、$rss->channel->item は定義されないため、RSS 2.0 としての情報の取得が失敗し、以下のif文が実行されます。
...
if (empty($single)) {
// 失敗したら Atom とみなして、ひとつのトピックについての情報を取得
$isAtom = true;
$single = $rss->entry;
}
...
$isAtom が true であれば対象のXMLがAtomであると判断し、それに応じて後に取得するタグを変更します。Atom としての取得が失敗した場合は RSS 1.0 とみなして、以下のif文を実行します。
...
if (empty($single)) {
// 失敗したら RSS 1.0 とみなして、ひとつのトピックについての情報を取得
$isRSS1 = true;
$single = $rss;
}
...
その後、条件に合うデータタグの取得を試みます。
...
if ($isRSS1) {
// RSS 1.0
$link = $info->link;
$dc_date = $info->children('http://purl.org/dc/elements/1.1/');
$date = date('Y/m/d', strtotime($dc_date->date));
} else if ($isAtom) {
// Atomの場合
$link = $info->link['href'];
$date = date("Y/m/d", strtotime($info->updated));
$description = $info->content;
} else {
// RSS 2.0
$link = $info->link;
$date = date("Y/m/d", strtotime($info->pubDate));
$description = $info->description;
}
...
以下は、奈良先端科学技術大学院大学のプレスリリースのAtomから時間とタイトルのみを取得した例です。RSS 2.0 と同じように取得できます。
以上、PHPでRSSやAtomの情報を取得してページに表示する方法でした。








すみません。こちらの記事ですが、複数のRSSに対応させるにはどのようにすればよいのでしょうか。