2009-11-30

MessagePackのPHP Extensionを作りました

MessagePack は、id:viverさんが開発されたバイナリシリアライズ形式です。
http://d.hatena.ne.jp/viver/
http://msgpack.sourceforge.jp/

すでに、perl, ruby, pythonでは使えるようになっていますが、PHPだけはまだ無いようだったので作ってみました。

ソースはとりあえず以下からダウンロードできます。
http://sui2.is-a-geek.net/trac/raw-attachment/wiki/php_msgpack/php5-msgpack-0.1.0.tar.gz

python版のソースをベースにPHPに移植した感じになってます。


ビルドにはphpの開発環境が必要です。
Debian系のディストリビューションならphp5-devパッケージを入れれば必要なものは入ると思います。そのほかのUnix系OSでも、PHPのソースをダウンロードすれば必要なスクリプトは付属しています。

ソースをダウンロードして展開したら、以下のコマンドでインストールできます。
$ phpize
$ ./configure
$ make
$ sudo make install

make できたらPHPの.iniファイルに以下の行を追加します。
extension=msgpack.so
Debianなら/etc/php5/apache2/conf.d/や/etc/php5/cli/conf.d/以下にmsgpack.iniを配置してもOKです。


使い方はpython版と大体同じです。
$data = array(1, -1, true, false, null, "key" => "value");

// simple procedural usage
$serialized = msgpack_pack($data);
var_dump(msgpack_unpack($serialized));

オブジェクト指向型の呼び出し方法もサポートしています。
// OO usage
$obj = new Msgpack;
$serialized = $obj->packer($data);
var_dump($obj->unpacker($serialized));

Msgpackオブジェクトを使えば複数のオブジェクトを連続してデシリアライズできます。
// stream deserialize
$buf = pack("c*", 0x00, 0x40, 0x7f, 0xe0, 0xf0, 0xff);
$obj->feed($buf);
while ($obj->remain()) {
  var_dump($obj->unpacker(NULL));
}

他の言語のMessagePackと少し違うのは、array型を使用していない点です。
PHPは配列は実際には順番付けされたマップなので、 すべてmap型でシリアライズするように実装してます。
その分少しデータ量が増えてしまいますが、そこはあきらめました。

ベンチマークは後日調べてみる予定です。

ZenBackWidget