跳到内容

序列化器编码器

编辑此页

Serializer 组件提供了几个内置的编码器

JsonEncoder
此类在 JSON 中编码和解码数据。
XmlEncoder
此类在 XML 中编码和解码数据。
YamlEncoder
此编码器在 YAML 中编码和解码数据。此编码器需要 Yaml 组件
CsvEncoder
此编码器在 CSV 中编码和解码数据。

注意

您也可以创建自己的编码器来使用其他结构。请阅读下文的创建自定义编码器以了解更多信息。

当在 Symfony 应用程序中使用 Serializer 组件时,所有这些编码器默认都是启用的。

JsonEncoder

JsonEncoder 基于 PHP 的 json_encodejson_decode 函数,对 JSON 字符串进行编码和解码。

通过提供诸如 JSON_PRESERVE_ZERO_FRACTION 之类的选项来修改这些函数的操作方式可能很有用。您可以使用序列化上下文,通过键 json_encode_optionsjson_decode_options 分别传入这些选项

1
2
3
$this->serializer->serialize($data, 'json', [
    'json_encode_options' => \JSON_PRESERVE_ZERO_FRACTION,
]);

JSON 编码器的所有可用上下文选项是

json_decode_associative (默认值: false)
如果设置为 true,则将结果作为数组返回,否则返回嵌套的 stdClass 层级结构。
json_decode_detailed_errors (默认值: false)
如果设置为 true,则在解析 JSON 时抛出的异常会更具体。需要 seld/jsonlint 包。
json_decode_options (默认值: 0)
传递给 json_decode 函数的标志。
json_encode_options (默认值: \JSON_PRESERVE_ZERO_FRACTION)
传递给 json_encode 函数的标志。
json_decode_recursion_depth (默认值: 512)
设置最大递归深度。

CsvEncoder

CsvEncoder 对 CSV 进行编码和解码。有几个上下文选项可用于自定义编码器的行为

csv_delimiter (默认值: ,)
设置分隔值的字段分隔符(仅限一个字符)。
csv_enclosure (默认值: ")
设置字段包围符(仅限一个字符)。
csv_end_of_line (默认值: \n)
设置用于标记 CSV 文件中每行结尾的字符。

csv_escape_char (默认值: 空字符串)

7.2

csv_escape_char 选项在 Symfony 7.2 中已被弃用。

设置转义字符(最多一个字符)。

csv_key_separator (默认值: .)
设置展平期间数组键的分隔符
csv_headers (默认值: [], 从输入数据的键推断)
设置标题和数据列的顺序。例如,如果您将其设置为 ['a', 'b', 'c'] 并序列化 ['c' => 3, 'a' => 1, 'b' => 2],则顺序将为 a,b,c 而不是输入顺序 (c,a,b)。
csv_escape_formulas (默认值: false)
通过在包含公式的字段前添加 \t 字符来转义它们。
as_collection (默认值: true)
始终将结果作为集合返回,即使只解码一行也是如此。
no_headers (默认值: false)
设置为 false 将在反规范化时使用第一行作为标题,true 生成数字标题。
output_utf8_bom (默认值: false)
输出特殊的 UTF-8 BOM 以及编码数据。

XmlEncoder

此编码器将 PHP 值转换为 XML,反之亦然。

例如,采用一个规范化为以下内容的对象

1
$normalizedArray = ['foo' => [1, 2], 'bar' => true];

XmlEncoder 将像这样编码此对象

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8" ?>
<response>
    <foo>1</foo>
    <foo>2</foo>
    <bar>1</bar>
</response>

特殊的 # 键可用于定义节点的数据

1
2
3
4
5
6
7
8
9
10
['foo' => ['@bar' => 'value', '#' => 'baz']];

/* is encoded as follows:
   <?xml version="1.0"?>
   <response>
       <foo bar="value">
          baz
       </foo>
   </response>
 */

此外,以 @ 开头的键将被视为属性,而键 #comment 可用于编码 XML 注释

1
2
3
4
5
6
7
8
9
10
11
12
$encoder = new XmlEncoder();
$xml = $encoder->encode([
    'foo' => ['@bar' => 'value'],
    'qux' => ['#comment' => 'A comment'],
], 'xml');
/* will return:
   <?xml version="1.0"?>
   <response>
       <foo bar="value"/>
       <qux><!-- A comment --!><qux>
   </response>
 */

您可以传递上下文键 as_collection,以便始终将结果作为集合。

注意

您可能需要在根节点上添加一些属性

1
2
3
4
5
6
7
8
9
10
11
12
$encoder = new XmlEncoder();
$encoder->encode([
    '@attribute1' => 'foo',
    '@attribute2' => 'bar',
    '#' => ['foo' => ['@bar' => 'value', '#' => 'baz']]
], 'xml');

// will return:
// <?xml version="1.0"?>
// <response attribute1="foo" attribute2="bar">
// <foo bar="value">baz</foo>
// </response>

提示

默认情况下,解码内容时会忽略 XML 注释,但可以使用可选的上下文键 XmlEncoder::DECODER_IGNORED_NODE_TYPES 更改此行为。

默认情况下,带有 #comment 键的数据被编码为 XML 注释。可以通过将 \XML_COMMENT_NODE 选项添加到 XmlEncoder 构造函数的 $defaultContextXmlEncoder::ENCODER_IGNORED_NODE_TYPES 键,或直接添加到 encode() 方法的 $context 参数来更改此设置

1
$xmlEncoder->encode($array, 'xml', [XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [\XML_COMMENT_NODE]]);

XmlEncoder 上下文选项

以下是在序列化器上下文上可用的选项

xml_format_output (默认值: false)
如果设置为 true,则使用换行符和缩进格式化生成的 XML。
xml_version (默认值: 1.0)
设置 XML 版本属性。
xml_encoding (默认值: utf-8)
设置 XML 编码属性。
xml_standalone (默认值: true)
在生成的 XML 中添加 standalone 属性。
xml_type_cast_attributes (默认值: true)
这提供了忘记属性类型转换的能力。
xml_root_node_name (默认值: response)
设置根节点名称。
as_collection (默认值: false)
始终将结果作为集合返回,即使只解码一行也是如此。
decoder_ignored_node_types (默认值: [\XML_PI_NODE, \XML_COMMENT_NODE])
要在解码时忽略的节点类型数组 (DOM XML_* 常量)。
encoder_ignored_node_types (默认值: [])
要在编码时忽略的节点类型数组 (DOM XML_* 常量)。
load_options (默认值: \LIBXML_NONET | \LIBXML_NOBLANKS)
XML 加载 选项与 libxml
save_options (默认值: 0)
XML 保存 选项与 libxml
remove_empty_tags (默认值: false)
如果设置为 true,则删除生成的 XML 中的所有空标签。
cdata_wrapping (默认值: true)
如果设置为 false,则不会将包含以下字符之一的值(<>&)包装在 CDATA 区段中,例如:<![CDATA[...]]>
cdata_wrapping_pattern (默认值: ``/[<>&]/``)
用于确定是否应将值包装在 CDATA 区段中的正则表达式模式。

7.1

cdata_wrapping_pattern 选项在 Symfony 7.1 中引入。

使用自定义 context 的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use Symfony\Component\Serializer\Encoder\XmlEncoder;

$data = [
    'id' => 'IDHNQIItNyQ',
    'date' => '2019-10-24',
];

$xmlEncoder->encode($data, 'xml', ['xml_format_output' => true]);
// outputs:
// <?xml version="1.0"?>
// <response>
//   <id>IDHNQIItNyQ</id>
//   <date>2019-10-24</date>
// </response>

$xmlEncoder->encode($data, 'xml', [
    'xml_format_output' => true,
    'xml_root_node_name' => 'track',
    'encoder_ignored_node_types' => [
        \XML_PI_NODE, // removes XML declaration (the leading xml tag)
    ],
]);
// outputs:
// <track>
//   <id>IDHNQIItNyQ</id>
//   <date>2019-10-24</date>
// </track>

YamlEncoder

此编码器需要 Yaml 组件,并在 Yaml 之间进行转换。

与其他编码器一样,有几个上下文选项可用

yaml_inline (默认值: 0)
您切换到内联 YAML 的级别。
yaml_indent (默认值: 0)
缩进级别(内部使用)。
yaml_flags (默认值: 0)
Yaml::DUMP_*/Yaml::PARSE_* 常量的位字段,用于自定义编码/解码 YAML 字符串。

创建自定义编码器

假设您想要序列化和反序列化 NEON。为此,您必须创建自己的编码器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// src/Serializer/YamlEncoder.php
namespace App\Serializer;

use Nette\Neon\Neon;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;

class NeonEncoder implements EncoderInterface, DecoderInterface
{
    public function encode($data, string $format, array $context = [])
    {
        return Neon::encode($data);
    }

    public function supportsEncoding(string $format)
    {
        return 'neon' === $format;
    }

    public function decode(string $data, string $format, array $context = [])
    {
        return Neon::decode($data);
    }

    public function supportsDecoding(string $format)
    {
        return 'neon' === $format;
    }
}

提示

如果您需要在 supportsDecodingsupportsEncoding 方法中访问 $context,请确保相应地实现 Symfony\Component\Serializer\Encoder\ContextAwareDecoderInterfaceSymfony\Component\Serializer\Encoder\ContextAwareEncoderInterface

在您的应用中注册它

如果您使用 Symfony 框架,那么您可能希望将此编码器注册为应用程序中的服务。如果您使用的是默认 services.yaml 配置,则会自动完成!

如果您没有使用自动配置,请确保将您的类注册为服务,并使用 serializer.encoder 标记它

1
2
3
4
5
6
# config/services.yaml
services:
    # ...

    App\Serializer\NeonEncoder:
        tags: ['serializer.encoder']

现在您将能够序列化和反序列化 NEON!

本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本