Introduction of Net_KyotoTycoon_Rest

この記事は PHP Advent Calendar jp 2010 Day 18 として書いてます。今日は丁寧な言葉で書きますw
前日は id:koyhoge さんの「PDO_pgsqlでハマった件 (PHP Advent Calendar 2010 17日目) - Blog::koyhoge::Tech」でした。


何について書こうかなーと悩みましたが、Tokyo/Kyoto シリーズの作者で Web 界隈の方たちはお世話になってる方が多いであろう平林幹雄さん([twitter:@mikio1978])が今「Kyoto Tycoon普及大作戦」をされており、また拙作の Net_KyotoTycoon について取り上げて頂いたので、少し書きたいと思います。
# 少しでもKyoto Tycoon 普及の支援になればいいなぁ。

Kyoto Tycoon を PHP で使うには

Kyoto Tycoon を PHP から使うには拙作の Net_KyotoTycoon を Openpear 経由でインストールして貰うのが一番簡単ですが、動作環境が PHP5.3 以上としています。
PHP5.3 以上に限定しているのには色々理由がありますが割愛します。


PHP5.3 以上を使えるという方は以下のコマンドでインストールできます。

$ sudo pear channel-discover openpear.org
$ sudo pear install openpear/Net_KyotoTycoon-beta

$ ktserver -port 1978 とかでポート番号を指定し Kyoto Tycoon を起動すれば利用できます。

PHP5.2 以前で使いたい

さて、環境が依然 PHP5.2 だったり、RHEL5/CentOS5 の PHP 環境をそのまま使っていると PHP5.2 どころか PHP5.1 だったりで、Net_KyotoTycoon が使えないという場合があります。


その場合は RESTful API 経由で PUT/GET/DELETE リクエストを発行するだけで最低限の操作ができるはずです。
平林さんのサイトには Ruby/Python3/Perl の RESTful API のサンプルが書かれています。
PHP は無いのでちょっと書いてみました。

ktserver の実行ログ。

2010-12-17T23:19:49.628865+09:00: [INFO]: connected: expr=127.0.0.1:50797
2010-12-17T23:19:49.629883+09:00: [INFO]: (127.0.0.1:50797): PUT /foo HTTP/1.1: 201
2010-12-17T23:19:49.631937+09:00: [INFO]: (127.0.0.1:50797): GET /foo HTTP/1.1: 200
2010-12-17T23:19:49.633168+09:00: [INFO]: (127.0.0.1:50797): DELETE /foo HTTP/1.1: 204
2010-12-17T23:19:49.640889+09:00: [INFO]: disconnecting: expr=127.0.0.1:50797

ね?簡単でしょ?


ただし以下のように setBody('') を書かなかったら不具合が発生しました。

<?php
public function remove($key)
{
    $uri     = $this->_base . urlencode($key);
    $headers = array(
        'Content-Length' => 0,
        'Connection'     => 'Keep-Alive',
        'Keep-Alive'     => 300,
    );

    $response = $this->_client->setMethod(HTTP_Request2::METHOD_DELETE)
                              ->setHeader($headers)
                              ->setUrl($uri)
//                           ->setBody('')
                              ->send();
    return $response->getStatus() === 204;
}
2010-12-17T23:24:29.232753+09:00: [INFO]: connected: expr=127.0.0.1:50685
2010-12-17T23:24:29.233906+09:00: [INFO]: (127.0.0.1:50685): PUT /foo HTTP/1.1: 201
2010-12-17T23:24:29.237160+09:00: [INFO]: (127.0.0.1:50685): GET /foo HTTP/1.1: 200
2010-12-17T23:24:29.240494+09:00: [INFO]: (127.0.0.1:50685): hogeDELETE /foo HTTP/1.1: 501
2010-12-17T23:24:29.243401+09:00: [INFO]: disconnecting: expr=127.0.0.1:50685

DELETE を発行した際に hogeDELETE となっています。
どうやら GET を発行した後に発生しているようです。
PUT -> DELETE という順番でやった場合には発生しませんでした。
問題の切り分けのために他の言語での RESTful なサンプルを試してみましたが、当然ながら発生しませんでした。


色々原因を探ってみた所、どうやら、setBody() で突っ込んだ値がそのまま残ってる模様です…。
バグなのか仕様なのか分からなかったですが、setBody('') と空文字を渡してやる事で解決できます。

まとめ

  • PHP5.3 で Kyoto Tycoon を使う場合は Openpear で RPC 経由で
  • PHP5.2 以前で Kyoto Tycoon を使う場合は RESTFul API 経由で

TSV-RPC を使った Net_KyotoTycoon の方は一通り API が揃っているので、色々やるにはそっちの方がお勧めです。


なお Kyoto Tycoon 自体には素敵なプラグイン機構がついており、先日 id:viver さんが MessagePack-RPC を組み込まれました。
Kyoto Tycoon に MessagePack-RPC をプラグインして Java から使う - Blog by Sadayuki Furuhashi
Java からの接続のサンプルですが、PHP も行けるんじゃないでしょうか(未確認ですが)。


さて明日は PHPフレームワーク Sabel の開発者で知られる id:hamaco さんです。