今回は,PHP用のライブラリとして,Syck for PHP,php_yaml,Spycの3つのライブラリを紹介します。
Syck for PHP
Syckは,Cで書かれたYAML用のライブラリです。もともとはRuby 1.8に付属しているライブラリですが,PHP用のバインディングが用意されています。
Syck for PHPについて
| Webサイト | http://whytheluckystiff.net/syck/ |
|---|---|
| ダウンロード | http://pecl.php.net/package/syck |
| バ-ジョン | 0.9.2 |
| ドキュメント | なし |
| その他 | PHP 5.2.1以上,PEAR Installer 1.4.0以上が必要 |
| 作者 | Alexey Zakhlestin |
インストール
インストールは(リスト1)のように行ってください。
リスト1 Syck for PHPのインストール
$ wget http://pecl.php.net/get/syck-0.9.2.tgz $ sudo pear install syck-0.9.2.tgz $ ls /usr/local/lib/php/extensions/no-debug-non-zts-20060613/ syck.so # syck.so があることを確かめる $ sudo vi /usr/local/lib/php.ini ### 以下を追加する ### extension_dir = "/usr/local/lib/php/extensions/no-debug-non-zts-20060613"
使い方
PHPにおけるSyckの使い方は,リスト2のとおりです。基本的に次の関数だけが用意されており,YAMLストリームの読み込みはできません。
- syck_load()
- YAMLドキュメントを読み込む
- syck_dump()
- データをYAMLドキュメントに変換する
syck_dump()において,日付と日時(timestamp)はDateTimeクラスのオブジェクトに変換されます。
リスト2 PHPにおけるSyckの使い方(ex-phpsyck1.php)
<?php
// 拡張モジュールsyck.soを読み込む
if (! extension_loaded('syck')) {
dl('syck.so') or die('cannot load syck extension.');
}
// YAMLドキュメントを読み込む
$str = file_get_contents("example.yaml");
$ydoc = syck_load($str);
var_dump($ydoc);
// データをYAMLドキュメントに変換
echo syck_dump($ydoc);
?>
日本語の扱い
読み込み(syck_load())については,EUCやUTF-8であればsyck_load()で問題ないようです。書き出し(syck_dump())については,日本語はたとえば「\xE3\x81\x84」のようにエンコードされます。エンコードされた文字列でもsyck_load()で問題なく読み込めますが,気になる場合はRubyの場合と同様にSyckのソースコードにパッチを当てることで,エンコードされるのを回避できます。詳しくはRubyでのSyckのセクションをご覧ください。
不具合
yck for PHPは,RubyのSyckと同じ不具合を抱えています。筆者が試したところ,その他に次のような不具合がありました。
- syck_load()
- 循環構造を持つデータがあるとエラーになる(リスト3)
- syck_dump()
- 独自クラスのインスタンスオブジェクトがYAMLへ変換できない
- 配列が循環構造を持っているとエラー(Segmentation fault)になる(リスト4)
syck_dump()を使うなら,現状ではインスタンスオブジェクトは諦めて,代わりに配列を使ったほうがよさそうです。
リスト3 syck_load()は循環構造があるとエラー(SyckException)になる
- &m1
name: Foo
child:
name: Bar
parent: *m1
リスト4 syck_dump()は循環構造があるとSegmentation faultになる
<?php
$arr1 = array(10);
$arr2 = array(20);
$arr1[] =& $arr2;
$arr2[] =& $arr1;
echo syck_dump($arr1);
?>
その他
PHPでは,無限配列(ArrayやList)と連想配列(HashやMap)の区別がありません。そのため,PHPの配列をsyck_dump()でYAMLドキュメントに変換するとき,YAMLのシーケンスに変換するのか,それともマッピングに変換するのかが問題になります。
実際の動作としては,次のようになるようです(リスト5)。
- インデックスが0から始まり,かつ連続していた場合はシーケンスに変換
- それ以外の場合はマッピングに変換
リスト5 PHPにおける配列の変換(ex-phpsyck2.php)
<?
// インデックスが0から始まり連続していた場合は
// シーケンスへ変換される
$arr = array();
$arr[0] = 10;
$arr[1] = 20;
$arr[2] = 30;
echo syck_dump($arr); //=> [10, 20, 30]
// インデックスが連続していない場合は
// マッピングへ変換される
$arr = array();
$arr[0] = 10;
$arr[2] = 30;
echo syck_dump($arr); //=> {0: 10, 2: 30}
?>

