前回の公開したrssLoader
実はRSS2.0だとitemタグを解析できないというバグがある
どこが悪くて読み込めないかというと以下の部分
1 2 3 4 | // 各記事を取得する 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」としなければならないのだ
修正したソースは以下のようになる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | <?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の要素を取得 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の要素を取得 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の要素を取得 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の要素を取得 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″]