YAML パーザ改良の巻

php_yaml-0.0.1devel3.tgz
以前のバージョンではクォートされていないスカラー値の int/float 判定と、int/float のパース処理はかなり手を抜いていて、PHP 組み込みのものを使っていました。そのため 2進数、60進数、可読性のためにアンダースコアが途中に入っている数値文字列が解釈できなかったのですが、その部分を自前で書いて YAML 1.1 仕様に添って記述されている数値型すべてを正しく PHP の数値型に変換できるようにしました。
(YAML 1.1 仕様には明記されていませんが、公式サイトのサンプルにあるのでカンマも数値区切り文字として許可するようにしています)


上記を含むすべての変更点は以下の通りです。

  • 数値型のパース処理を改良
  • php.ini のエントリを追加
    • yaml.decode_binary (default: Off)
      • On にすると binary 型 (tag:yaml.org,2002:binary) の値を Base64 デコードする
    • yaml.decode_timestamp (default: 0)
      • 0: timestamp 型 (tag:yaml.org,2002:timestamp) の値を文字列のままにしておく
      • 1: timestamp 型の値を UNIX エポック秒 (integer) に変換する
      • 2: timestamp 型の値を元にした DateTime クラスのインスタンスを生成する。PHP 5.2 以降の date エクステンションが必要
  • yaml_parse* 関数の第四引数で特定のタグを処理するコールバック関数を連想配列で指定できるようにした。配列の各要素は、キーがタグ名、値が関数名もしくは array(class_or_object, method) で、タグ名は tag:yaml.org,2002:omap のように完全な形式で指定する (!omap のようなショートカットは使えない)


新機能の使用例は examples/test3.php にあります。このスクリプトコマンドラインで以下のようにして使います。(同じ階層にある test.php, test2.php も同様です)

cd php_yaml-0.0.1devel3/examples
php test3.php $n # $n = サンプル番号 (0-28,99)

example22.yaml の場合はこのような出力が得られるはずです。


PHP 5.2

% php-5.2 test3.php 22
+----------+
|   YAML   |
+----------+
canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -5
date: 2002-12-14

+----------+
|  RESULT  |
+----------+
array(1) {
  [0]=>
  array(4) {
    ["canonical"]=>
    object(DateTime)#1 (0) {
    }
    ["iso8601"]=>
    object(DateTime)#2 (0) {
    }
    ["spaced"]=>
    object(DateTime)#3 (0) {
    }
    ["date"]=>
    object(DateTime)#4 (0) {
    }
  }
}

PHP 4.4

% php-4.4 test3.php 22
+----------+
|   YAML   |
+----------+
canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -5
date: 2002-12-14

+----------+
|  RESULT  |
+----------+
array(1) {
  [0]=>
  array(4) {
    ["canonical"]=>
    int(1008385183)
    ["iso8601"]=>
    int(1008385183)
    ["spaced"]=>
    int(1008385183)
    ["date"]=>
    int(1039791600)
  }
}