如何在PHP中解析Ruby的YAML(sfYaml和Spyc不会正确)

时间:2013-04-24 18:20:19

标签: php yaml

我在MySQL中有以下值(由ChiliProject制作):

--- 
author_id: 
- 0
- 1
status_id: 
- 0
- 1
subject: 
- ""
- !binary |
  0KHQtNC10LvQsNGC0Ywg0LPRgNCw0LzQvtGC0L3Ri9C5INCy0L3QtdGI0L3Q
  uNC5INCy0LjQtCDQtNC70Y8g0LjQvNC10Y7RidC10LPQvtGB0Y8=

start_date: 
- 
- 2012-04-30
priority_id: 
- 0
- 4
tracker_id: 
- 0
- 2
description: 
- 
- ""
project_id: 
- 0
- 2
created_on: 
- 
- 2012-04-30 17:51:08.596410 +04:00

sfYaml说:无法解析第11行(靠近“0KHQtNC10LvQsNGC0Ywg0LPRgNCw0LzQvtGC0L3Ri9C5INCy0L3QtdGI0L3Q”)。

Spyc将“ - ”项添加到与author_id,status_id等相同的级别。看起来合理(因为没有间距),但Ruby的YAML正在解释它。 Spyc也忽略了base64。

sfYaml和Spyc不够可靠吗?

有什么建议吗?我可以使用哪种解析器或技巧从PHP使用此数据库?

1 个答案:

答案 0 :(得分:1)

这是我的解决方案:

<强> RubyYaml.php:

<?php

class RubyYaml
{
    static public function parse($data)
    {
        $descriptorSpec = array(
            0 => array("pipe", "r"),  // stdin
            1 => array("pipe", "w"),  // stdout
            //2 => array("pipe", "a"),  // stderr
        );

        $process = proc_open('ruby '.__DIR__.'/yaml2json.rb', $descriptorSpec, $pipes);

        if (!is_resource($process))
            throw new CException('Cannot start YAML parser');

        fwrite($pipes[0], $data);
        fclose($pipes[0]);

        $json = stream_get_contents($pipes[1]);
        fclose($pipes[1]);

        proc_close($process);

        $result = json_decode($json, true);
        if ($result === null) // Don't your YAMLs contain plain NULL ever?
            throw new CException('YAML parsing failed: '.$json);

        return $result;
    }
}

<强> yaml2json.rb:

require "json"
require 'yaml'

def recursion(v)

  if v.class == String
    v.force_encoding('utf-8')

  elsif v.class == Array
    v.each do |vv|
      recursion(vv)
    end

  elsif v.class == Hash
    v.each do |k, vv|
      recursion(vv)
    end

  end

end


thing = YAML.load(STDIN.read)

recursion(thing)

puts thing.to_json