unoh.github.com

PHPでTokyoTyrantのストリームラッパーを書く

Thu Aug 13 11:10:58 -0700 2009

浴衣の女の子は大好きですが、僕が近づくと逃げいていきます。 Keitaです。

さて、ちょっと前にNet_TokyoTyrantを公開しましたがぽつぽつと修正をかけて いたります。外国の方もちょくちょくTokyoTyrantを使ってる人がいるようで、2,3回 バグ報告をいただきました。Openpearに移動し誰でもコミットできるような状態になっ てますのでバグとか見つけたりしたら、遠慮なくコミットしてください。

さて、とある方にPHPのストリームラッパが結構簡単に書けることを教えていただいたのでTokyoTyrantで試してみたいと思います。

簡単に説明すると以下のようにファイルとしてfopenとかfile_get_contentsが使うための仕組みががPHPで簡単にできます。

<?php
//こんなphpのコードをあらかじめ書き込んでおいて
$test1 ='<?php $a = 11;';
$tt->put('test1.php', $test1);

//allow_url_openがonならrequire
require "tokyotyrant://localhost:1978/test1.php";


//ファイル書き込んで
file_put_contents("tokyotyrant://localhost:1978/test3.php", 'himote');
//himoteってでたら成功
file_get_contents("tokyotyrant://localhost:1978/test3.php");

こんなことしてみたいです。

拡張書かなくちゃできないんじゃない?とか思ってたんですが、結構昔から、phpだけでできるようで、マニュアルにもちゃんと記載があります。まぁよく考えてみれば、ほかの言語やってたときはばりばりストリームクラスとか作ってたなーと思い反省することしきりなのです。

さて、作り方についてですが、ざっくりいってしまうと、stream_wrapper_registerで特定のメソッドを用意したクラスを登録してあげるだけです。

拙作のNet_TokyoTyrantをインストールして、読み込めるパスに配置したあとに、Stream_TokyoTyrantを落としてきてつかってみてください。たぶん最初のコードが動くと思います。

実にその作りも単純でソースをはしょって説明すると、

<?php
class Stream_TokyoTyrant
{
//---中略---
// ファイルオープンして
    public function stream_open($path, $mode, $options, &$opened_path)
    {
        $url = parse_url($path);
        $port = $url['port'];
        $server = $url['host'];
        try {
            $this->tt = $this->getTokyoTyrant($port, $server);
        } catch (Exception $e){
            return false;
        }
        $this->key = $this->nomalizePath($url['path']);
        $this->data = $this->tt->get($this->key);//面倒なのでここで全部データ読み込んじゃう
        $this->position = 0;
        return true;
    }
//
// ファイルを読み込んだ結果を返す(少しずつ読み込むのが本当のストリームだけどね!)
    function stream_read($count)
    {
        $ret = substr($this->data, $this->position, $count);
        $this->position += strlen($ret);
        return $ret;
    }
}

ほとんどのコードが本家のサンプルにあるコードそのままです。

簡単ですね。

ざっくり適当につくっただけなのでバグいっぱいありそうですが(接続きってないし・・)かなり簡単に使えることがわかっていただけたかと思います。

最初、下記のよなコードを書きたかったんです。

//allow_url_openがonならrequire
require "tokyotyrant://localhost:1978/test1.php";

でも、たぶん気がついた人はたくさんいると思いますがTokyoTyrantはhttpプロトコルもしゃべるので

//allow_url_openがonならrequire
require "http://localhost:1978/test1.php";

ふつーにこういうコードも動くんですね。あとで気がつきました。

まぁ消えたらこまる(php的な)キャッシュファイル置き場として使うと早そうと思いました。

ご参考になれば幸いです。

追記: 調べたら、Stream_VarというPearのパッケージがあるみたいです。なんかしばらくメンテナンスされてない風味だったんですが最近更新されてるようですね。試してはいないですのでなんらかのヒントになれば幸いです。