序列化器编码器
Serializer 组件提供了几个内置的编码器
- JsonEncoder
- 此类在 JSON 中编码和解码数据。
- XmlEncoder
- 此类在 XML 中编码和解码数据。
- YamlEncoder
- 此编码器在 YAML 中编码和解码数据。此编码器需要 Yaml 组件。
- CsvEncoder
- 此编码器在 CSV 中编码和解码数据。
注意
您也可以创建自己的编码器来使用其他结构。请阅读下文的创建自定义编码器以了解更多信息。
当在 Symfony 应用程序中使用 Serializer 组件时,所有这些编码器默认都是启用的。
JsonEncoder
JsonEncoder
基于 PHP 的 json_encode 和 json_decode 函数,对 JSON 字符串进行编码和解码。
通过提供诸如 JSON_PRESERVE_ZERO_FRACTION
之类的选项来修改这些函数的操作方式可能很有用。您可以使用序列化上下文,通过键 json_encode_options
或 json_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
构造函数的 $defaultContext
的 XmlEncoder::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;
}
}
提示
如果您需要在 supportsDecoding
或 supportsEncoding
方法中访问 $context
,请确保相应地实现 Symfony
或 Symfony
。
在您的应用中注册它
如果您使用 Symfony 框架,那么您可能希望将此编码器注册为应用程序中的服务。如果您使用的是默认 services.yaml 配置,则会自动完成!
如果您没有使用自动配置,请确保将您的类注册为服务,并使用 serializer.encoder 标记它
1 2 3 4 5 6
# config/services.yaml
services:
# ...
App\Serializer\NeonEncoder:
tags: ['serializer.encoder']
现在您将能够序列化和反序列化 NEON!