序列化器编码器
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!