Yaml组件

Yaml组件用于加载和剥离YAML文件。

它是什么? 

Symfony的Yaml组件对YAML字符串进行解析并把它们转换成PHP数组。它也能转换PHP数组成为YAML字符串。

YAMLYAML Ain't Markup Language,是一个对所有编程语言都十分友好的序列化标准(serialization standard)。YAML对配置文件来说是极好的格式。YAML文件在表达力上有如XML文件,但可读性上有如INI文件。

Symfony的Yaml组件实现的是一个由 YAML协议1.2版 所定义的“经过选择的”功能子集。

阅读 the YAML Format 一文以了解Yaml组件的更多内容。

安装 

你可以通过下述两种方式安装:

然后,包容vendor/autoload.php文件,以开启Composer提供的自动加载机制。否则,你的程序将无法找到这个Symfony组件的类。

为什么是它? 

快 

Symfony Yaml的目标之一就是在速度和功能性之间找到一个平衡点。它支持在处理配置文件是“按需配置”。明显欠缺的功能是:document directives, multi-line quoted messages, compact block collections and multi-document files(文档指令,多行带引号信息,短小块集合,和多文档文件)。

真正的解析器 

组件支持一个真正的解析器,能够解析YAML协议的巨大子集,满足你配置过程的全部所需。这意味着其解析器极为健壮,易于理解,扩展时足够简单。

清晰的错误信息 

当你在YAML文件中出现语法问题时,组件库会输出帮助信息,包括问题发生的文件名和行号信息。大幅度简化了调试。

支持剥离 

组件也支持把YAML文件剥离成PHP数组并提供对象支持,以及对美化输出所需的“行内级别配置”(inline level configuration)的支持。

支持类型 

组件支持YAML内建的绝大多数类型,包括日期、整形、八进制、布尔,乃至更多...

支持完整的键合并 

对引用(reference)、假名、完整键合并(full merge key)的完整支持。对常用配置(文件)进行包容,即可避免重复(代码)操作。

使用Symfony YAML组件 

Symfony Yaml组件极其简单,它有两个主要的类:一个用来解析YAML字符串 (Parser),另一个是把PHP数组给剥离成一个YAML字符串 (Dumper)。

在这两个类的基础上, Yaml 类作为一个轻量级打包器来简化常用操作。

读取YAML文件 

parse() 方法解析一个YAML字符串,并将其转换为PHP数组:

1
2
3
use Symfony\Component\Yaml\Yaml;
 
$value = Yaml::parse(file_get_contents('/path/to/file.yml'));

因为目前还不可能向本方法传入一个文件名,你必须首先验证输入内容。传入文件名从Symfony 2.2起,不建议再使用,将从Symofny 3.0中移除。

如果解析过程有错误发生,parser会抛出一个 ParseException 异常,来指示产生错误的原始YAML字符串中的错误类型和行号:

1
2
3
4
5
6
7
use Symfony\Component\Yaml\Exception\ParseException;
 
try {
    $value = Yaml::parse(file_get_contents('/path/to/file.yml'));
} catch (ParseException $e) {
    printf("Unable to parse the YAML string: %s", $e->getMessage());
}

写入YAML文件 

dump() 方法可将任意PHP数组,剥离为它所对应的YAML:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Yaml\Yaml;
 
$array = array(
    'foo' => 'bar',
    'bar' => array('foo' => 'bar', 'bar' => 'baz'),
);
 
$yaml = Yaml::dump($array);
 
file_put_contents('/path/to/file.yml', $yaml);

如果在剥离过程有错误发生,parser会抛出一个 DumpException 异常。

数组展开化和行内化 

YAML格式支持两种类型的数组呈现,展开型,行内型。默认时,dumper使用展开化的数组:

1
2
3
4
foo: bar
bar:
    foo: bar
    bar: baz

dump()方法的第二个参数可以自定义“从展开型数组切换为行内型数组”的输出级别:

1
echo Yaml::dump($array, 1);
1
2
foo: bar
bar: { foo: bar, bar: baz }
1
echo Yaml::dump($array, 2);
1
yaml

缩进 

默认时,YAML组件使用四个空格的缩进。通过下例中的第三个参数可以改变:

1
2
// use 8 spaces for indentation / 使用8个空格的缩进
echo Yaml::dump($array, 2, 8);
1
2
3
4
foo: bar
bar:
        foo: bar
        bar: baz

高级用法:Flags 

3.1 旗标从Symfony 3.1开始引入,取代了之前的boolean参数。

对象的解析和剥离 

使用 DUMP_OBJECT 旗标即可剥离对象:

1
2
3
4
5
$object = new \stdClass();
$object->foo = 'bar';
 
$dumped = Yaml::dump($object, 2, 4, Yaml::DUMP_OBJECT);
// !php/object:O:8:"stdClass":1:{s:5:"foo";s:7:"bar";}

使用 PARSE_OBJECT 旗标即可解析它们:

1
2
3
$parsed = Yaml::parse($dumped, Yaml::PARSE_OBJECT);
var_dump(is_object($parsed)); // true
echo $parsed->foo; // bar

YAML组件使用PHP的 serialize() 方法来生成对象的字符串呈现。

对象的序列化是这个实现所独有的。其他的PHP YAML解析器都难以辨别 php/object 标签,非PHP实现更应当特别小心,不要使用。

处理无效类型 

默认时,parser将对无效类型比如 null 进行编码(encode)。使用 DUMP_EXCEPTION_ON_INVALID_TYPE 旗标,你就可以让解析器抛出异常:

1
2
$yaml = '!php/object:O:8:"stdClass":1:{s:5:"foo";s:7:"bar";}';
Yaml::parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); // throws an exception

类似的,在dumping过程中,使用 DUMP_EXCEPTION_ON_INVALID_TYPE 旗标以抛出异常:

1
2
3
4
$data = new \stdClass(); // by default objects are invalid.
Yaml::dump($data, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE); // throws an exception
 
echo $yaml; // { foo: bar }

日期处理 

默认时,YAML parser会把“看起来像日期或日期-时间”的未加引号字符串(unqouted strings)转换成一个Unix时间戳;例如 2016-05-272016-05-27T02:59:43.1Z (ISO-8601):

1
Yaml::parse('2016-05-27'); // 1464307200

使用 PARSE_DATETIME 旗标,你可以把它们转换成 DateTime 实例:

1
2
$date = Yaml::parse('2016-05-27', Yaml::PARSE_DATETIME);
var_dump(get_class($date)); // DateTime

剥离多行的文字块 

YAML中的多行内容,能够以文字块(literal blocks)呈现,默认时,dumper将把这些“多行内容”当作一个“行内字符串”来进行编码

1
2
3
$string = array("string" => "Multiple\nLine\nString");
$yaml = Yaml::dump($string);
echo $yaml; // string: "Multiple\nLine\nString"

使用 DUMP_MULTI_LINE_LITERAL_BLOCK 旗标,就可以让dumper输出文字块:

1
2
3
4
5
6
7
$string = array("string" => "Multiple\nLine\nString");
$yaml = Yaml::dump($string, 2, 4, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
echo $yaml;
//  string: |
//       Multiple
//       Line
//       String

了解更多

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)