Zend_Feedのlink($rel)が上手く動かない

| トラックバック(1)

cacheから取り出したデータについては今のところ100%正しい結果を得られるけど、HTTPでとって来たデータだと2回に1回失敗。

Atomの<link rel="next" type="~" href="http://~" />から次のURLを抜き出す処理をしてるんだけど、どうも2回に1回は失敗する。シリアライズして保存しているcacheデータを使った場合は失敗しない。

cacheにはオブジェクトをシリアライズして保存しているので、cacheデータを使う時にはZend_Feed内で行っているDOM処理が無い。一方、HTTPでとって来た場合、毎回DOM処理が入る。この辺が原因なのかな?

PHPのDOMDocumentを使う場合、後処理とかしないと駄目なのかな。Zend_Feedの後処理が必要なのかな?


追記:
とりあえず、cacheに入れてからそれを取り出して使うようにしました。
DOMオブジェクトであるべき変数が、文字列のままになっているようです。なんだろ。処理の呼び出し順序とか?
きっと、DOMDocumentとかZend_Feedとかじゃなくて、自分のコードの方に問題があるんでしょう。

一応、問題になってるソースコード貼っときます。

<?php
 
if (!defined("HATENA_BOOKMARK_ATOMFEED_SLEEP_TIME")) {
    define("HATENA_BOOKMARK_ATOMFEED_SLEEP_TIME", 30);
}
 
require_once "Zend/Feed.php";
require_once "Zend/Cache.php";
 
require_once "HTTP/Request.php";
 
class Hatena_Bookmark_Atomfeed
{
 
    private $username;
    private $cache;
    private $time;
    private $url;
    private $http;
    private $feed;
    private $isVerbose;
 
    public function __construct($username, $cacheConfig, $useragent, $time = 0, $isVerbose = false)
    {
        $this->isVerbose = $isVerbose;
        $this->username  = $this->_filterUsername($username);
        $this->cache     = Zend_Cache::factory("Core",
                                               "Sqlite",
                                               array(
                                                     "lifeTime" => 86400,
                                                     "automaticSerialization" => true
                                                     ),
                                               array(
                                                     "cacheDBCompletePath" => $cacheConfig["path"]
                                                     ));
        $this->time    = intval($time);
        $this->url     = "http://b.hatena.ne.jp/" . $this->username . "/atomfeed";
        $this->_setupHttp($useragent);
 
        $this->feed        = $this->_import($this->url);
    }
 
    private function _filterUsername($username)
    {
        return preg_replace("/[^0-9a-zA-Z]/", "", $username);
    }
 
    private function _filterId($id)
    {
        return preg_replace("/[^\d]/", "", $id);
    }
 
    private function _setupHttp($useragent)
    {
        $this->http = new HTTP_Request("",
                                       array(
                                             "timeout"       => 60,
                                             "allowRedirect" => true,
                                             "maxRedirect"   => 3,
                                             ));
        $this->http->addHeader("User-Agent", $useragent);
    }
 
    public function fetch()
    {
        // test feed initialize
        if (is_null($this->feed)) {
            return null;
        }
 
        // test next entry or feed
        if (!$this->feed->valid()) {
            $nextUrl = $this->feed->link("next");
            if ($nextUrl == null) {
                if ($this->isVerbose) {
                    echo "no next\n";
                }
                return null;
            }
            $this->feed = $this->_import($nextUrl);
            if ($this->feed == null) {
                if ($this->isVerbose) {
                    echo "import-error: $nextUrl\n";
                }
                return null;
            }
        }
 
        $entry = $this->feed->current();
 
        // test sync diff
        if ($this->time > strtotime($entry->issued())) {
            return null;
        }
 
        // go next entry
        $this->feed->next();
 
        // build entry data
        return $this->_entryArray($entry);
    }
 
    private function _entryArray($entry)
    {
        return array(
                     "atom_id"   => $entry->id(),
                     "title"     => $entry->title(),
                     "url"       => $entry->link("related"),
                     "summary"   => $entry->summary(),
                     "tags"      => $this->_getTags($entry),
                     "timestamp" => strtotime($entry->issued()),
                     );
    }
 
    private function _getTags($entry)
    {
        $tags     = "";
        $subjects = $entry->{"dc:subject"};
        if (is_array($subjects) and count($subjects) > 0) {
            $tags = '[' . implode("][",
                                  array_map(create_function('$e', 'return $e->__toString();'),
                                            $subjects)) . ']';
        } else {
            $tags = "[" . $subjects->__toString() . "]";
        }
        return $tags;
    }
 
    private function _import($url)
    {
        if (($feed = $this->cache->get($this->_getCacheId($url)))) {
            if ($this->isVerbose) {
                echo "cache: $url\n";
            }
            return $feed;
        }
        try {
            $this->feed = null;
            $this->http->setURL($url);
            if (PEAR::isError($this->http->sendRequest())) {
                if ($this->isVerbose) {
                    echo "request-error: $url\n";
                }
                return null;
            } else {
                if ($this->isVerbose) {
                    echo "load: $url\n";
                }
            }
            $feed = Zend_Feed::importString($this->http->getResponseBody());
            $this->cache->save($feed, $this->_getCacheId($url));
            if ($this->isVerbose) {
                echo "wait...";
            }
            sleep(HATENA_BOOKMARK_ATOMFEED_SLEEP_TIME);
            if ($this->isVerbose) {
                echo "start\n";
            }
            return $this->cache->get($this->_getCacheId($url));
        } catch (Zend_Feed_Exception $e) {
            if ($this->isVerbose) {
                echo "import-error: $url\n";
            }
            return null;
        }
    }
 
    private function _getCacheId($seed) {
        return md5($seed);
    }
 
}
 
?>

トラックバック(1)

職業プログラマの戯言 - Zend_Feed (2008年4月 5日 11:31)

RSSのパースにはMagpieRSSを使っているのですが、せっかくZendFrameworkをインストールしたのだから、その中に含まれるZend_Feed... 続きを読む

プロフィール

このブログ記事について

このページは、koshigoeが2006年10月15日 22:11に書いたブログ記事です。

ひとつ前のブログ記事は「『PHPのissetはnullが入っているとfalseを返す』事を知らず戸惑った」です。

次のブログ記事は「UTF-8からUTF-8に変換したら通った」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。