HOME>WEBプログラム覚書>PHPとYAML

PHPとYAML

設定ファイルとか書くのはYAMLって形式が簡単でいいらしい。

YAMLとは?

下記サイトがとても詳しくわかりやすく書かれているので読む。

  • データを「配列」「ハッシュ」「スカラー (数値や文字列や真偽値)」だけで表す
  • XMLより「読みやすい」「書きやすい」「わかりやすい」フォーマット
  • フロースタイルという形式で書けばJSONとしても扱える
  • 仕様書によると文字コードはユニコードだけどEUCとかでも問題なさそう

PHPで扱うには?

簡単な方法はspycっていうクラスをダウンロードするだけ。
PHPの拡張モジュールとしてSyckっていうのがあるのでPHPの環境触れる場合はそちらを使ったほうがいいのかも。
でも機能がYAMLリーダだけ?

テストコード

サンプルのYAMLはRubyist Magazine - プログラマーのための YAML 入門 (初級編)そのままです。

spyc.phpの中身

読み込むとSpycってクラスとspyc_load ($string)、function spyc_load_file ($file) って関数が利用できるようになる。
この2つの関数はSpyc::YAMLLoadString($string)とSpyc::YAMLLoad($file)を単に呼び出してるだけなので、
どちらを利用してもよさそう。関数使ったほうがいいのかな?

配列

sample1.yaml

  1. - aaa
  2. - bbb
  3. - ccc
  4.  

PHP

  1. <?php
  2. require_once('spyc.php');
  3. $yaml = spyc_load_file('sample1.yaml');
  4.  
  5. var_dump($yaml);
  6. ?>

実行結果

array(3) { [0]=> string(3) "aaa" [1]=> string(3) "bbb" [2]=> string(3) "ccc" }

ネストされた配列

sample2.yaml

  1. - aaa
  2. -
  3.   - b1
  4.   - b2
  5.   -
  6.     - b3.1
  7.     - b3.2
  8. - ccc
  9.  

PHP

  1. <?php
  2. require_once('spyc.php');
  3. $yaml = spyc_load_file('sample2.yaml');
  4.  
  5. var_dump($yaml);
  6. ?>

実行結果

array(3) { [0]=> string(3) "aaa" [1]=> array(3) { [0]=> string(2) "b1" [1]=> string(2) "b2" [2]=> array(2) { [0]=> string(4) "b3.1" [1]=> string(4) "b3.2" } } [2]=> string(3) "ccc" }

連想配列

sample3.yaml

  1. A: aaa
  2. B: bbb
  3. C: ccc
  4.  

PHP

  1. <?php
  2. require_once('spyc.php');
  3. $yaml = spyc_load_file('sample3.yaml');
  4.  
  5. var_dump($yaml);
  6. ?>

実行結果

array(3) { ["A"]=> string(3) "aaa" ["B"]=> string(3) "bbb" ["C"]=> string(3) "ccc" }

ネストされた連想配列

sample4.yaml

  1. A: aaa
  2. B:
  3.   B1: bbb1
  4.   B2: bbb2
  5. C: ccc
  6.  

PHP

  1. <?php
  2. require_once('spyc.php');
  3. $yaml = spyc_load_file('sample4.yaml');
  4.  
  5. var_dump($yaml);
  6. ?>

実行結果

array(3) { ["A"]=> string(3) "aaa" ["B"]=> array(2) { ["B1"]=> string(4) "bbb1" ["B2"]=> string(4) "bbb2" } ["C"]=> string(3) "ccc" }

データ型の確認

sample5.yaml

  1. decimal1:  123                           # 整数 (10 進数)
  2. decimal2:  1,234,567,890                 # 整数 (10 進数)
  3. octal:     0644                          # 整数 (8 進数)
  4. hexa:      0xFF                          # 整数 (16 進数)
  5. float1:    0.05                          # 浮動小数点
  6. bool1:     true                          # 真
  7. bool2:     yes                           # 真
  8. bool3:     on                            # 真
  9. bool4:     false                         # 偽
  10. bool5:     no                            # 偽
  11. bool6:     off                           # 偽
  12. null1:     ~                             # Null 値
  13. null2:     null                          # Null 値
  14. date:      2005-01-01                    # 日付
  15. stamp:     2005-01-01 00:00:00 +09:00    # タイムスタンプ
  16. str1:      'true'                      # 文字列
  17. str2:      "2005"                        # 文字列
  18. symbol:    :foo                          # シンボル (Syck の独自機能)
  19.  

PHP

  1. <?php
  2. echo 'PHP_VERSION : ', PHP_VERSION, '<br />';
  3. $yaml = spyc_load_file('sample5.yaml');
  4. echo '<pre>';
  5. var_dump($yaml);
  6. echo '</pre>';
  7. ?>

実行結果

PHP_VERSION : 5.6.40
array(18) {
  ["decimal1"]=>
  int(123)
  ["decimal2"]=>
  string(13) "1,234,567,890"
  ["octal"]=>
  float(644)
  ["hexa"]=>
  float(0)
  ["float1"]=>
  float(0.05)
  ["bool1"]=>
  bool(true)
  ["bool2"]=>
  bool(true)
  ["bool3"]=>
  bool(true)
  ["bool4"]=>
  bool(false)
  ["bool5"]=>
  bool(false)
  ["bool6"]=>
  bool(false)
  ["null1"]=>
  NULL
  ["null2"]=>
  NULL
  ["date"]=>
  string(10) "2005-01-01"
  ["stamp"]=>
  string(26) "2005-01-01 00:00:00 +09:00"
  ["str1"]=>
  string(8) "\'true\'"
  ["str2"]=>
  string(6) ""2005""
  ["symbol"]=>
  string(4) ":foo"
}

PHPに無い型はともかくとして、その他もアテにならない模様。

JSON(sample6.yaml)

YAMLをフロースタイルで書くとJSONと等価になる。

JSON

  1. { "menu": {
  2.     "id": "file",
  3.     "value": "File:",
  4.     "popup": {
  5.       "menuitem": [
  6.         {"value": "New", "onclick": "CreateNewDoc()"},
  7.         {"value": "Open", "onclick": "OpenDoc()"},
  8.         {"value": "Close", "onclick": "CloseDoc()"}
  9.       ]
  10.     }
  11.   }
  12. }
  13.  

PHP

  1. <?php
  2. $yaml = spyc_load_file('sample6.yaml');
  3.  
  4. echo '<pre>';
  5. var_dump($yaml);
  6. echo '</pre>';
  7. ?>

実行結果

array(2) {
  ["{ "menu""]=>
  array(5) {
    ["id"]=>
    string(7) ""file","
    ["value"]=>
    string(8) ""File:","
    ["popup"]=>
    array(1) {
      ["menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick"]=>
      string(15) ""CloseDoc()"} ]"
    }
    [0]=>
    string(1) "}"
    [1]=>
    string(1) "}"
  }
  [0]=>
  string(1) "}"
}

PHPのspycでは対応していないみたいです。{}がダメっぽい。JSONの場合はjson_decode()を使う。

PHP

  1. <?php
  2. echo '<pre>';
  3. var_dump(json_decode(file_get_contents('sample6.yaml')));
  4. echo '</pre>';
  5. ?>

実行結果

object(stdClass)#162 (1) {
  ["menu"]=>
  object(stdClass)#163 (3) {
    ["id"]=>
    string(4) "file"
    ["value"]=>
    string(5) "File:"
    ["popup"]=>
    object(stdClass)#164 (1) {
      ["menuitem"]=>
      array(3) {
        [0]=>
        object(stdClass)#165 (2) {
          ["value"]=>
          string(3) "New"
          ["onclick"]=>
          string(14) "CreateNewDoc()"
        }
        [1]=>
        object(stdClass)#166 (2) {
          ["value"]=>
          string(4) "Open"
          ["onclick"]=>
          string(9) "OpenDoc()"
        }
        [2]=>
        object(stdClass)#167 (2) {
          ["value"]=>
          string(5) "Close"
          ["onclick"]=>
          string(10) "CloseDoc()"
        }
      }
    }
  }
}

配列からYAMLへ

Spyc::YAMLDump()、Spyc::dump()が用意されている。Spyc::YAMLDump()はstaticにアクセス可能。

YAMLを読み込んで再びYAMLにしてみる。

実行結果

array(3) {
  ["A"]=>
  string(3) "aaa"
  ["B"]=>
  array(2) {
    ["B1"]=>
    string(4) "bbb1"
    ["B2"]=>
    string(4) "bbb2"
  }
  ["C"]=>
  string(3) "ccc"
}

string(43) "---
A: aaa
B:
  B1: bbb1
  B2: bbb2
C: ccc
"

「---」はひとつのファイルに複数のYAMLを記述するためのもの。ただしPHPのSpycは対応してないっぽい?

---で区切られたYAML

sample7.yaml

  1. ---
  2. - aaa
  3. - bbb
  4. - ccc
  5. ---
  6. - ddd
  7. - eee
  8. - fff
  9.  

PHP

  1. <?php
  2. $yaml = spyc_load_file('sample7.yaml');
  3.  
  4. echo '<pre>';
  5. var_dump($yaml);
  6. echo '</pre>';
  7. ?>

実行結果

array(6) {
  [0]=>
  string(3) "aaa"
  [1]=>
  string(3) "bbb"
  [2]=>
  string(3) "ccc"
  [3]=>
  string(3) "ddd"
  [4]=>
  string(3) "eee"
  [5]=>
  string(3) "fff"
}

1個の配列で返ってくる。嫌な場合は自力で分割。

PHP

  1. <?php
  2. $arr = preg_split('/^---$/m', file_get_contents($yaml_sample . 'sample7.yaml'));
  3.  
  4. $yamls = array();
  5. foreach ($arr as $yaml) {
  6.     if (!empty($yaml)) {
  7.         $yamls[] = spyc_load($yaml);
  8.     }
  9. }
  10.  
  11. echo '<pre>';
  12. var_dump($yamls);
  13. echo '</pre>';
  14. ?>

実行結果

array(2) {
  [0]=>
  array(3) {
    [0]=>
    string(3) "aaa"
    [1]=>
    string(3) "bbb"
    [2]=>
    string(3) "ccc"
  }
  [1]=>
  array(3) {
    [0]=>
    string(3) "ddd"
    [1]=>
    string(3) "eee"
    [2]=>
    string(3) "fff"
  }
}

ってかsplit()非推奨になったんだ。

投稿日 2009年12月 2日 22:26
カテゴリ PHP
タグ テストコード | ライブラリ
トラックバック URL http://www.kantenna.com/cgi-bin/mt504/mt-tb.cgi/1197

コメント

コメントする
Name
Email Address
URL