CakePHPでSimplePieを扱ってGoogle NewsのFeedを取得してみようと思い、まずダウンロードし中に含まれているsimplepie.incファイルを\vendorsファイル内置いた後、以下のようなコードを書いてみました。PHPのバージョンは5.3、SimplePieのバージョンは1.2、CakePHPのバージョンは1.2.6
まずはコントローラーの作成。モデルは使用しない。\app\controllers\feeds_controller.phpに保存
<?php
class FeedsController extends AppController {
var $name = 'Feeds';
var $uses = array();
App::import('Vendor', 'SimplePie', array('file' => 'simplepie.inc'));
$SimplePie = new SimplePie();
$SimplePie->set_cache_location(CACHE);
$SimplePie->set_cache_duration(3600);
$SimplePie->feed_url = 'http://news.google.com/news?hl=en&ned=us&ie=UTF-8&oe=UTF-8&output=rss&q=Wii';
$SimplePie->set_input_encoding('UTF-8');
$SimplePie->set_output_encoding();
$SimplePie->init();
$SimplePie->handle_content_type();
$this->set(array('feed' => $SimplePie));
}
}
?>
次はビューの作成。テスト用なので簡潔に。\app\views\feeds\index.ctpに保存。
<ul>
<?php foreach($feed->get_items() as $item) : ?>
<li>
<?php echo $html->link($item->get_title(), $item->get_link()); ?>
<?php echo $item->get_link(); ?>
</li>
<?php endforeach; ?>
</ul>
実際に/Feeds/indexにアクセスし無事表示され万事うまくいったかと思いきや、リンクをクリックしてみると以下のようなメッセージが表示されてしまう。
表示中のページから無効な URL にリダイレクトしようとしています。
このページにリダイレクトしないようにする場合は、前のページに戻ってください。
URLが無効ということはGoogle NewsのFeed自体が壊れているのかと、実際にWebブラウザでhttp://news.google.com/news?hl=en&ned=us&ie=UTF-8&oe=UTF-8&output=rss&q=WiiへアクセスしてURLを確かめるも何もおかしいとこはない。むしろ個別の記事へ普通にアクセスできる。
となるとSimplePieになにかあるのかと調べてみると、URL処理において不可解な部分が。たとえばAtomのatom:entry内のatom:linkのURLではhttp://news.google.com/news/url?fd=R&sa=T&url=http%3A%2F%2Fwww.examiner.com%2Fx-13000-NY-Wii-Examiner~y2010m2d13-Nintendo-Wii-games-lead-video-game-sales&usg=AFQjCNHUHrzx3QhGmyLDiDlQ5IJjx8l8tgとなっているがSimplePieを通して表示したURLはhttp://news.google.com/news/url?fd%3DR%26sa%3DT%26url%3Dhttp://www.examiner.com/x-13000-NY-Wii-Examiner~y2010m2d13-Nintendo-Wii-games-lead-video-game-sales%26usg%3DAFQjCNHUHrzx3QhGmyLDiDlQ5IJjx8l8tgとなっている。明らかに無駄にURLエンコードが行われている。
simplepie.incのコードを追って行くとreplace_invalid_with_pct_encodingがURLのencodeをしている模様。
どうもライブラリの根幹の部分みたいなので下手に変更するのも気が引ける。早く修正してほしい限り。代わりにXML_Feed_Parserでも使用してみるかな。

