Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

GMailFeedクラス

ちょっと今更なネタですが、個人的には最近になって知ったので。。。;-)
GMailのFeedはhttpsBASIC認証なので、取得する仕組みとしてはさほど難しくはありません。phpclassesではGmAtomが登録されていますが、curl拡張モジュールが必要です。まあ、最近はbuildするようにしているので問題はないのですが、curlを使わずにできないかなぁ、と。
ということで、PHPマニュアルにあったStream拡張のサンプルを使って、新着メールを取り出すクラスを作ってみました。結構便利ですよ > Stream拡張

<?php
/**
 * GMailFeedクラス
 *
 * @author SHIMOOKA Hideyuki <shimooka@doyouphp.jp>
 * @create 2006/11/12
 */
class GmailFeed {
    private static $GMAIL_FEED_URL = 'https://mail.google.com/mail/feed/atom';
    private $authorization;
    private $label;

    /**
     * コンストラクタ
     * @param string GMailのユーザー名
     * @param password パスワード
     */
    public function __construct($username, $password) {
        $this->authorization = base64_encode($username . ':' . $password);
        $this->label = '';
    }

    /**
     * ラベル名を取得する
     * @return string ラベル名。初期値は空文字
     */
    public function getLabel() {
        return $this->label = $label;
    }

    /**
     * ラベル名を取得する
     * @param string ラベル名。文字列のみ有効
     * @throws RuntimeException
     */
    public function setLabel($label) {
        if (!is_string($label)) {
            throw new RuntimeException('Invalid value for label');
        }
        $this->label = $label;
    }

    /**
     * Feedを取得する
     * @throws RuntimeException
     */
    public function getFeed() {
        return $this->_get();
    }

    /**
     * FeedをSimpleXMLElementオブジェクトとして取得する
     * @throws RuntimeException
     */
    public function getFeedAsSimpleXml() {
        return new SimpleXMLElement($this->_get());
    }

    private function _get() {
        $options = array(
                       'http' => array(
                           'method' => "GET",
                           'header' => "Authorization: Basic ". $this->authorization
                        )
                   );

        $context = stream_context_create($options);

        $url = self::$GMAIL_FEED_URL;
        if ($this->label !== '') {
            $url .= '/' . $this->label;
        }
        $fp = @fopen($url, 'rb', false, $context);
        if ($fp === false) {
            throw new RuntimeException('Failed to connect');
        }

        $contents = @stream_get_contents($fp);
        if ($contents === false) {
            throw new RuntimeException('Failed to get contents');
        }
        fclose($fp);

        return $contents;
    }
}

クライアント側は次のような感じ。

<?php
require 'GmailFeed.class.php';

$username = 'YOUR USERNAME';
$password = 'YOUR PASSWORD';

/**
 * 未読メールのFeedを取得
 */
$gmail = new GmailFeed($username, $password);
var_dump(mb_convert_encoding($gmail->getFeed(), mb_internal_encoding(), 'utf-8'));

/**
 * 未読メールのFeedをSimpleXMLElementオブジェクトを取得
 */
$elements = $gmail->getFeedAsSimpleXml();
echo '<ul>';
foreach ($elements->entry as $entry) {
    $title = mb_convert_encoding($entry->title, mb_internal_encoding(), 'utf-8');
    printf('<li>[%s] <a href="%s" title="%s">%s</a></li>',
           $entry->issued,
           $entry->link['href'],
           $title,
           $title);
}
echo '</ul>';

/**
 * ラベル「phpsec」が付いた未読メールのFeedを
 * SimpleXMLElementオブジェクトを取得
 */
$gmail->setLabel('phpsec');
$elements = $gmail->getFeedAsSimpleXml();
echo '<ul>';
foreach ($elements->entry as $entry) {
    $title = mb_convert_encoding($entry->title, mb_internal_encoding(), 'utf-8');
    printf('<li>[%s] <a href="%s" title="%s">%s</a></li>',
           $entry->issued,
           $entry->link['href'],
           $title,
           $title);
}
echo '</ul>';

try {
    /**
     * RuntimeExceptionが発生する
     */
    $gmail->setLabel(null);
}
catch (Exception $e) {
    var_dump($e->getMessage());
}

動作確認はPHP5.2.0のみです。SimpleXMLをサポートしてるなら、PHP5.1.xでも動作すると思います。あと、クラス側はちょこっと書き換えれば、PHP4向けにもなると思います。
やっぱ、SimpleXML便利すぎ! :-D