前回の公開したrssLoader
実はRSS2.0だとitemタグを解析できないというバグがある
どこが悪くて読み込めないかというと以下の部分
// 各記事を取得する foreach($rssDom->item as $item) { $itemBean = new itemBean();
「RSSのフォーマット・仕様・構造 – RSS1.0、RSS2.0、Content-Type」を見ていただくと分かるが
RSS1.0ではitemタグはchannelタグと同列のDom階層に存在するが
RSS2.0ではitemタグはchannelタグ配下のDom階層にある
RSS2.0を読み込むには「$rssDom->channel->item」としなければならないのだ
修正したソースは以下のようになる
<?php require_once __DIR__."/channelBean.php"; require_once __DIR__."/itemBean.php"; require_once __DIR__."/rssException.php"; require_once __DIR__."/lib/httpConnecter.php"; require_once __DIR__."/lib/xmlLoader.php"; class rssLoader { const VERSION_1 = 1; const VERSION_2 = 2; const VERSION_ALL = 0; public function __construct() { } public function __destruct() { } /** * RSSを読み込みchannelBeanで取得 * * @param int $version 対象RSSバージョン指定 * 全バージョンのRSS : rssLoader::VERSION_ALL * バージョン1.0のRSS : rssLoader::VERSION_1 * バージョン2.0のRSS : rssLoader::VERSION_2 * */ public function loadRss($path, $version = self::VERSION_ALL) { /** * RSSを取得 */ $http = new httpConnecter(); $http->connect($path); $rssStr = $http->loadText(); if($rssStr === "") { // 取得できなければエラー throw rssException::notRss("RSSファイルの取得ができませんでした。"); } /** * RSSを解析 */ $xml = new xmlLoader(); $rssDom = $xml->parsor($rssStr); // すべてのバージョン if($version == self::VERSION_ALL) { try { return $this->loadRss2($rssDom); } catch (Exception $e) { return $this->loadRss1($rssDom); } } // rss1.0 else if(isset($rssDom->attributes()->version) == false && $version == self::VERSION_1) { return $this->loadRss1($rssDom); } // rss2.0 else if($rssDom->attributes()->version == 2 && $version == self::VERSION_2) { return $this->loadRss2($rssDom); } else { throw rssException::notMatchVersion("このRSSは正しい型式ではありません。"); } return $channelBean; } /** * RSS1.0を解析 * @param unknown $rssDom */ private function loadRss1($rssDom) { //if($rssDom->attributes()->version != self::VERSION_1) { // throw rssException::notMatchVersion("このRSSはVertion1.0ではありません。"); //} $channelBean = new channelBean(); $channelBean->encoding = "UTF-8"; $channelBean->rssVersion = self::VERSION_1; $channelBean->rssUrl = $rssDom->channel->link; // RSSの本体情報を取得 if(isset($rssDom->channel->title)) { $channelBean->title = $rssDom->channel->title; } if(isset($rssDom->channel->link)) { $channelBean->link = $rssDom->channel->link; } if(isset($rssDom->channel->description)) { $channelBean->description = $rssDom->channel->description; } // dcの要素を取得 $dc = $rssDom->channel->children('http://purl.org/dc/elements/1.1/'); if(isset($dc->date)) { $channelBean->date = $dc->date; } if(isset($dc->language)) { $channelBean->language = $dc->language; } if(isset($dc->creator)) { $channelBean->creator = $dc->creator; } // ver1.0各記事を取得する foreach($rssDom->item as $item) { $itemBean = new itemBean(); if(isset($item->title)) { $itemBean->title = $item->title; } if(isset($item->link)) { $itemBean->link = $item->link; } if(isset($item->description)) { $itemBean->description = $item->description; } if(isset($item->category)) { $itemBean->category = $item->category; } if(isset($item->pubDate)) { $itemBean->date = $item->date; } // dcの要素を取得 $dc = $item->children('http://purl.org/dc/elements/1.1/'); if(isset($dc->date)) { $itemBean->date = $dc->date; } if(isset($dc->subject)) { $itemBean->category = $dc->subject; } if(isset($dc->creator)) { $itemBean->creator = $dc->creator; } array_push($channelBean->itemList, $itemBean); } return $channelBean; } /** * RSS2.0を解析 * @param unknown $rssDom */ private function loadRss2($rssDom) { if($rssDom->attributes()->version != self::VERSION_2) { throw rssException::notMatchVersion("このRSSはVertion2.0ではありません。"); } $channelBean = new channelBean(); $channelBean->encoding = "UTF-8"; $channelBean->rssVersion = self::VERSION_2; $channelBean->rssUrl = $rssDom->channel->link; // RSSの本体情報を取得 if(isset($rssDom->channel->title)) { $channelBean->title = $rssDom->channel->title; } if(isset($rssDom->channel->link)) { $channelBean->link = $rssDom->channel->link; } if(isset($rssDom->channel->description)) { $channelBean->description = $rssDom->channel->description; } // dcの要素を取得 $dc = $rssDom->channel->children('http://purl.org/dc/elements/1.1/'); if(isset($dc->date)) { $channelBean->date = $dc->date; } if(isset($dc->language)) { $channelBean->language = $dc->language; } if(isset($dc->creator)) { $channelBean->creator = $dc->creator; } // ver2.0各記事を取得する foreach($rssDom->channel->item as $item) { $itemBean = new itemBean(); if(isset($item->title)) { $itemBean->title = $item->title; } if(isset($item->link)) { $itemBean->link = $item->link; } if(isset($item->description)) { $itemBean->description = $item->description; } if(isset($item->category)) { $itemBean->category = $item->category; } if(isset($item->pubDate)) { $itemBean->date = $item->date; } // dcの要素を取得 $dc = $item->children('http://purl.org/dc/elements/1.1/'); if(isset($dc->date)) { $itemBean->date = $dc->date; } if(isset($dc->subject)) { $itemBean->category = $dc->subject; } if(isset($dc->creator)) { $itemBean->creator = $dc->creator; } array_push($channelBean->itemList, $itemBean); } return $channelBean; } }
上記ソースはほかにもネームスペース「dc」の要素が読み込めていない問題などを修正している
ダウンロードはこちらから→[download id=”1″]