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に対応させるにはどのようにすればよいのでしょうか。