Serializer组件

编辑本页

要使用Serializer组件,请设置序列化器指定哪些编码器和规范化器将可用:

1 2 3 4 5 6 7 8 9
使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器编码器XmlEncoder使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器编码器= (XmlEncoder (),JsonEncoder ()];标准化者= (ObjectNormalizer ()];序列化器序列化器(标准化者编码器);

首选的归一化器是ObjectNormalizer,但其他归一化器是可用的。下面显示的所有示例都使用ObjectNormalizer

现在,如果你想将这个对象序列化为JSON,你只需要使用之前创建的Serializer服务:

12 3 4 5 6 7 8 9 10 11 12
使用应用程序模型人();->setName (“foo”);->setAge (99);->setSportsperson ();jsonContent序列化器->序列化(json的);// $jsonContent包含{"name":"foo","age":99,"sportsperson":false,"createdAt":null}回声jsonContent//或在响应中返回它

的第一个参数serialize ()在这种情况下,对象是要序列化的,第二个是用来选择合适的编码器的吗JsonEncoder

人类将以XML格式编码:

1 2 3 4 5 6 7 8 9 10 11
使用应用程序模型数据<< foo 99 false  EOF;序列化器->反序列化(数据,人::类,“xml”);

在这种情况下,反序列化()需要三个参数:

  1. 要解码的信息
  2. 此信息将被解码到的类的名称
  3. 用于将该信息转换为数组的编码器

默认情况下,没有映射到非规范化对象的附加属性将被Serializer组件忽略。如果希望在发生这种情况时抛出异常,请设置AbstractNormalizer: ALLOW_EXTRA_ATTRIBUTES上下文选项。并提供一个实现ClassMetadataFactoryInterface在构造规范化器时:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
使用应用程序模型数据< < < EOF <人> <名称> foo < /名称> < > 99岁年龄< / > < >城市巴黎城市< / > < > /人EOF;// $loader是本文后面解释的任何有效加载器classMetadataFactoryClassMetadataFactory (加载程序);标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);//这将抛出Symfony\Componeob娱乐下载nt\Serializer\Exception\ExtraAttributesException//因为“city”不是Person类的属性序列化器->反序列化(数据,人::类,“xml”, [AbstractNormalizer .::ALLOW_EXTRA_ATTRIBUTES = >]);

这是使用ORM时的一个常见需求。

AbstractNormalizer: OBJECT_TO_POPULATE仅用于顶级对象。如果该对象是树结构的根,那么规范化数据中存在的所有子元素都将使用新实例重新创建。

AbstractObjectNormalizer: DEEP_OBJECT_TO_POPULATE选项设置为true,即根的现有子节点OBJECT_TO_POPULATE从规范化数据更新,而不是由反规范化程序重新创建它们。请注意,DEEP_OBJECT_TO_POPULATE只适用于单个子对象,但不适用于对象数组。当它们出现在规范化数据中时,仍然会被替换。

序列化的定义可以使用注释、XML或YAML来指定。的ClassMetadataFactory归一化器将使用的对象必须知道要使用的格式。

对象的初始化方法的代码如下ClassMetadataFactory对于每种格式:

  • PHP文件中的注释:

    1 2 3 4 5
    使用学说常见的注释AnnotationReader使用ob娱乐下载组件序列化器映射工厂ClassMetadataFactory使用ob娱乐下载组件序列化器映射加载程序AnnotationLoaderclassMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));
  • YAML文件:

    1 2 3 4
    使用ob娱乐下载组件序列化器映射工厂ClassMetadataFactory使用ob娱乐下载组件序列化器映射加载程序YamlFileLoaderclassMetadataFactoryClassMetadataFactory (YamlFileLoader (“/道路/ /你/ definition.yaml”));
  • XML文件:

    1 2 3 4
    使用ob娱乐下载组件序列化器映射工厂ClassMetadataFactory使用ob娱乐下载组件序列化器映射加载程序XmlFileLoaderclassMetadataFactoryClassMetadataFactory (XmlFileLoader (“/道路/ /你/ definition.xml”));

然后,创建你的组定义:

  • 注释
  • 属性
  • YAML
  • XML
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
名称空间Acme使用ob娱乐下载组件序列化器注释MyObj/ * * *@Groups({"group1", "group2"}) */公共喷火/ * * *@Groups({}“group4”)* /公共anotherProperty/ * * *@Groups(“group3”)* /公共函数getBar()//方法支持返回->酒吧;}/ /……

你现在只能序列化你想要的组中的属性:

12 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 30
使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器objMyObj ();obj->foo =“foo”obj->anotherProperty =“anotherProperty”obj->setBar (“酒吧”);标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);数据序列化器->正常化(obj, (“组织”= >“group1”]);// $data = ['foo' => 'foo'];methoda序列化器->denormalize ([“foo”= >“foo”“anotherProperty”= >“anotherProperty”“酒吧”= >“酒吧”],“MyObj”, (“组织”= > [“group1”“group3”]]);// $obj2 = MyObj(foo: 'foo', bar: 'bar')//在' groups '中使用特殊值' * 'obj3序列化器->denormalize ([“foo”= >“foo”“anotherProperty”= >“anotherProperty”“酒吧”= >“酒吧”],“MyObj”, (“组织”= > [‘*’]]);// $obj2 = MyObj(foo: 'foo', anotherProperty: 'anotherProperty', bar: 'bar')

5.2

特殊值为在Symfony 5.2中引入。ob娱乐下载

只有不被忽略的属性(参见下面)是可用的。如果设置了一些序列化组,则只能使用这些组允许的属性。

对于组,可以在序列化和反序列化过程中选择属性。

@ ignore注释

  • 注释
  • 属性
  • YAML
  • XML
12 3 4 5 6 7 8 9 10 11 12 13
名称空间应用程序模型使用ob娱乐下载组件序列化器注释忽略MyClass公共喷火/ * * *@ ignore() * /公共酒吧;}

你现在可以在序列化过程中忽略特定的属性:

12 3 4 5 6 7 8 9 10 11 12 13
使用应用程序模型MyClass使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器objMyClass ();obj->foo =“foo”obj->酒吧=“酒吧”标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);数据序列化器->正常化(obj);// $data = ['foo' => 'foo'];

1 2 3 4 5
公司公共的名字公共地址;}

在序列化形式中,所有属性都必须以org_像下面这样:

1
“org_name”“Acme公司。”“org_address”“大城市主街123号”

自定义名称转换器可以处理以下情况:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
使用ob娱乐下载组件序列化器NameConverterNameConverterInterfaceOrgPrefixNameConverter实现了NameConverterInterface公共函数正常化(字符串propertyName返回“org_”propertyName;}公共函数denormalize(字符串propertyName//删除'org_'前缀返回“org_”= = = substr (propertyName04) ?substr (propertyName4):propertyName;}}

自定义名称转换器可以通过将其作为任何类扩展的第二个参数来使用AbstractNormalizer,包括GetSetMethodNormalizer而且PropertyNormalizer

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器nameConverterOrgPrefixNameConverter ();标准化者ObjectNormalizer (nameConverter);序列化器序列化器([标准化者]、[JsonEncoder ()));公司公司();公司->name =“Acme公司”。公司->地址=“大城市主街123号”json序列化器->序列化(公司json的);// {"org_name": "Acme Inc.", "org_address": "大城市主街123号"}companyCopy序列化器->反序列化(json、公司::类,json的);//与$company相同的数据

请注意

你也可以实现AdvancedNameConverterInterface访问当前类名、格式和上下文。

PSR-1标准对于属性名不推荐任何特定的情况)。

ob娱乐下载Symfony提供了一个内置的名称转换器,设计用于在序列化和反序列化过程中在snake_case和camelcases样式之间转换:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
使用ob娱乐下载组件序列化器NameConverterCamelCaseToSnakeCaseNameConverter使用ob娱乐下载组件序列化器标准化者ObjectNormalizer标准化者ObjectNormalizer (CamelCaseToSnakeCaseNameConverter ());私人firstName公共函数__constructfirstName->firstName =firstName;}公共函数getFirstName()返回->firstName;}}凯文人(“凯文”);标准化者->正常化(凯文);// ['first_name' => 'Kévin'];安妮标准化者->denormalize ([“first_name”= >“安妮”],“人”);// firstName: 'Anne'的Person对象

属性组部分,这已经设置好了,你只需要提供配置。否则:

12 3 4 5 6 7 8 9 10 11 12 13 14
/ /……使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器NameConverterMetadataAwareNameConverter使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器classMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));metadataAwareNameConverterMetadataAwareNameConverter (classMetadataFactory);序列化器序列化器([ObjectNormalizer (classMetadataFactorymetadataAwareNameConverter)]、[json的= >JsonEncoder ()));

现在配置您的名称转换映射。考虑一个应用程序,它定义了具有firstName属性:

  • 注释
  • 属性
  • YAML
  • XML
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
名称空间应用程序实体使用ob娱乐下载组件序列化器注释SerializedName/ * * *@SerializedName(“customer_name”)* /私人firstName公共函数__constructfirstName->firstName =firstName;}/ /……

这个自定义映射用于在序列化和反序列化对象时转换属性名:

1 2
序列化序列化器->序列化(人(“凯文”),json的);// {"customer_name": "Kévin"}

是,就像模型应用\ \人::isSportsperson ()), Serializer组件将自动检测并使用它来序列化相关属性。

ObjectNormalizer还关心从。开始的方法而且得到

12 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
使用应用程序模型使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器标准化者GetSetMethodNormalizer使用ob娱乐下载组件序列化器序列化器编码器JsonEncoder ();//所有回调参数都是可选的(你可以省略你不使用的参数)dateCallback函数innerObjectouterObject、字符串attributeName、字符串格式= null,数组上下文= [])返回innerObject运算符\ DateTime吗?innerObject->(\ DateTime格式::ISO8601):;};defaultContext= [AbstractNormalizer .::回调=> [“createdAt”= >dateCallback,],];标准化者GetSetMethodNormalizer (defaultContext);序列化器序列化器([标准化者]、[编码器]);人();->setName (“cordoval”);->setAge (34);->setCreatedAt (\ DateTime (“现在”));序列化器->序列化(json的);/ /输出:{“名称”:“cordoval”,“年龄”:34岁“createdAt”:“2014 - 03 - 22 - t09:43:12 - 0500 "}

NormalizerInterface用于规范化(对象到数组)和DenormalizerInterface用于反规格化(数组到对象)。

在序列化器中将规范化器作为第一个参数传递时启用:

1 2 3 4 5
使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器标准化者= (ObjectNormalizer ()];序列化器序列化器(标准化者[]);

ObjectNormalizer

这个归一化器利用PropertyAccess组件在对象中读写。这意味着它可以直接访问属性,并通过getter, setter, hassers, issers, adder和removers。它支持在反规格化过程中调用构造函数。

对象被规范化为属性名称和值的映射(名称是通过删除得到添加orgydF4y2Ba删除方法名的前缀,并将第一个字母转换为小写字母;如。getFirstName ()->firstName).

ObjectNormalizer是最强大的归一化器。它在启用Serializer组件的Symfony应用程序中默认ob娱乐下载配置。

GetSetMethodNormalizer

这个规范化器通过调用“getter”(以“get”开头的公共方法)来读取类的内容。它将通过调用构造函数和“setter”(以“set”开头的公共方法)来反规范化数据。

对象被规范化为属性名称和值的映射(名称是通过删除得到方法名的前缀,并将第一个字母转换为小写字母;如。getFirstName ()->firstName).

PropertyNormalizer

此规范化器直接读取和写入公共属性以及私人和受保护的属性(来自类及其所有父类)PHP反射.它支持在反规格化过程中调用构造函数。

对象被规范化为属性名到属性值的映射。

JsonSerializableNormalizer

此规范化器与实现的类一起工作JsonSerializable

它会调用JsonSerializable: jsonSerialize ()方法,然后进一步规范化结果。这意味着嵌套JsonSerializable类也将被规范化。

当您希望使用simple从现有代码库逐步迁移时,此规范化器特别有用json_encode到Symfonob娱乐下载y Serializer,允许您混合使用哪些归一化器用于哪些类。

json_encode可以处理循环引用。

DateTimeNormalizer
这个归一式转换DateTimeInterface对象(如。DateTime而且DateTimeImmutable)转换成字符串。默认情况下,它使用RFC3339格式。
DateTimeZoneNormalizer
这个归一式转换DateTimeZone时区对象转换为表示时区名称的字符串PHP时区列表
DataUriNormalizer
这个归一式转换SplFileInfo对象转换为数据URI字符串(数据:……)这样文件就可以嵌入到序列化的数据中。
DateIntervalNormalizer
这个归一式转换DateInterval对象转换为字符串。默认情况下,它使用P % dDT % % yY %毫米hH % iM %党卫军格式。
BackedEnumNormalizer

这个规范化器将backdenum对象转换为字符串或整数。

5.4

BackedEnumNormalizer在Symfony 5.4中引入。ob娱乐下载PHP backdenum至少需要PHP 8.1。

FormErrorNormalizer

此规范化器与实现的类一起工作FormInterface

它将从表单中获取错误,并将它们规范化到规范化数组中。

ConstraintViolationListNormalizer
此规范化器转换实现的对象ConstraintViolationListInterface的错误列表RFC 7807标准。
ProblemNormalizer
根据API问题规范规范错误RFC 7807
CustomNormalizer
使用实现的对象规范化PHP对象NormalizableInterface
UidNormalizer

此规范化器转换实现的对象AbstractUid为字符串。实现的对象的默认规范化格式UuidRFC 4122格式(例如:d9e7a184 - 5 - d5b - 11 - ea - a62a d0——3499710062).实现的对象的默认规范化格式Ulid是Base 32格式(例如:01 e439tp9xjz9rpfh3t1pybcr8).可以通过设置序列化器上下文选项更改字符串格式UidNormalizer: NORMALIZATION_FORMAT_KEYUidNormalizer: NORMALIZATION_FORMAT_BASE_58UidNormalizer: NORMALIZATION_FORMAT_BASE_32orgydF4y2BaUidNormalizer: NORMALIZATION_FORMAT_RFC_4122

它也可以去正规化uuidorgydF4y2Baulid字符串UuidorgydF4y2BaUlid.格式并不重要。

5.2

UidNormalizer在Symfony 5.2中引入。ob娱乐下载

5.3

UidNormalizer在Symfony 5.3中引入了规范化格式。ob娱乐下载

请注意

您还可以创建自己的Normalizer来使用其他结构。欲知详情,请浏览如何创建您的自定义规范化

在Symfony应用程序中使用Serializer组件时,某些规范化器默认启用,其他规范化器可以通过标记它们来启用ob娱乐下载serializer.normalizer

下面是一个如何启用内置的示例GetSetMethodNormalizer,一个更快的替代ObjectNormalizer

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7
#配置/ services.yaml服务:#……get_set_method_normalizer:类:ob娱乐下载Symfony \组件\ \标准化者\ GetSetMethodNormalizer进行序列化标签:(serializer.normalizer)

EncoderInterface用于编码(数组格式化)和DecoderInterface用于解码(格式到数组)。

你可以通过使用Serializer实例的第二个构造函数参数来添加新的编码器:

1 2 3 4 5 6
使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器编码器XmlEncoder使用ob娱乐下载组件序列化器序列化器编码器= (XmlEncoder (),JsonEncoder ()];序列化器序列化器([],编码器);

JsonEncoder
中的数据进行编码和解码JSON
XmlEncoder
中的数据进行编码和解码XML
YamlEncoder
这个编码器对数据进行编码和解码YAML.这个编码器需要Yaml组件
CsvEncoder
这个编码器对数据进行编码和解码CSV

请注意

您还可以创建自己的编码器来使用其他结构。欲知详情,请浏览如何创建自定义编码器

在Symfony应用程序中使用Serializer组件时,默认情况下启用所有这些编码器。ob娱乐下载

JsonEncoder

JsonEncoder编码和解码JSON字符串,基于PHPjson_encode而且json_decode功能。通过提供诸如。之类的选项来修改这些函数在某些情况下的操作方式是有用的JSON_PRESERVE_ZERO_FRACTION.您可以使用序列化上下文使用键来传递这些选项json_encode_optionsorgydF4y2Bajson_decode_options分别为:

1
->序列化器->序列化(数据json的, (“json_encode_options”= > \ JSON_PRESERVE_ZERO_FRACTION]);

CsvEncoder

CsvEncoder编码到CSV并从CSV解码。

CsvEncoder上下文选项

编码()方法定义了第三个可选参数上下文它为CsvEncoder定义了一个关联数组的配置选项:

1
csvEncoder->编码(数组“csv”上下文);

以下是可用的选项:

选项 描述 默认的
csv_delimiter 设置分隔值的字段分隔符(仅一个字符)
csv_enclosure 设置字段框(仅限一个字符)
csv_end_of_line 设置用于标记CSV文件中每行结束的字符 \ n
csv_escape_char 设置转义字符(最多一个字符) 空字符串
csv_key_separator 在数组压平期间为数组的键设置分隔符
csv_headers 设置标题和数据列的顺序$data = ['c' => 3, 'a' => 1, 'b' => 2]而且$options = ['csv_headers' => ['a', 'b', 'c']]然后Serialize ($data, 'csv', $options)返回a, b, c \ n1 2 3 [],从输入数据的键推断
csv_escape_formulas 在包含公式的字段前加上\ t字符
as_collection 总是以集合的形式返回结果,即使只解码了一行。 真正的
no_headers 在编码的CSV中禁用报头
output_utf8_bom 输出的特殊utf - 8 BOM与编码数据一起

5.3

csv_end_of_line选项在Symfony 5.3中引入。ob娱乐下载

XmlEncoder

这个编码器将数组转换为XML,反之亦然。

例如,取一个对象,规范化如下:

1
“foo”= > [12],“酒吧”= >真正的];

XmlEncoder将像这样编码这个对象:

1 2 3 4 5 6
<??> . xml version="1.0" encoding="UTF-8"<响应><喷火>1喷火><喷火>2喷火><酒吧>1酒吧>响应>

特殊的Key可以用来定义节点的数据:

1 2 3 4 5 6 7 8 9
“foo”= > [“@bar”= >“价值”“#”= >“记者”]];//编码如下://<?xml version = " 1.0 "? >/ /响应> <//  ./ /巴兹/ / < / foo >/ / < /响应>

此外,键以@将考虑属性,和关键#评论可以用来编码XML注释:

1 2 3 4 5 6 7 8 9 10 11
编码器XmlEncoder ();编码器->编码([“foo”= > [“@bar”= >“价值”],“qux”= > [“#评论”= >“评论”),),“xml”);//返回://<?xml version = " 1.0 "? >/ /响应> <//  ./ / < qux > < !——评论——!> < qux >/ / < /响应>

您可以传递上下文键as_collection为了有结果总是作为一个集合。

提示

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

数据与#评论默认情况下,键被编码为XML注释。这可以通过可选选项进行更改encoderIgnoredNodeTypes美元的参数XmlEncoder类的构造函数。

XmlEncoder上下文选项

编码()方法定义了第三个可选参数上下文它为XmlEncoder定义了一个关联数组的配置选项:

1
xmlEncoder->编码(数组“xml”上下文);

以下是可用的选项:

选项 描述 默认的
xml_format_output 如果设置为true,则使用换行和缩进格式化生成的XML
xml_version 设置XML版本属性 1.1
xml_encoding 设置XML编码属性 utf - 8
xml_standalone 在生成的XML中添加独立属性 真正的
xml_type_cast_attributes 这提供了忘记属性类型强制转换的能力 真正的
xml_root_node_name 设置根节点名称 响应
as_collection 总是以集合的形式返回结果,即使只解码了一行
decoder_ignored_node_types 节点类型数组(DOM XML_*常量)在解码时被忽略 [\ XML_PI_NODE \ XML_COMMENT_NODE]
encoder_ignored_node_types 节点类型数组(DOM XML_*常量)在编码时被忽略 []
load_options XML加载libxml的选项 \ libxml_nonet | \ libxml_noblanks
remove_empty_tags 如果设置为true,则删除生成的XML中的所有空标记

自定义示例上下文

12 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 30 31
使用ob娱乐下载组件序列化器编码器XmlEncoder//创建带有指定选项的编码器作为新的默认设置xmlEncoderXmlEncoder ([“xml_format_output”= >真正的]);数据= (“id”= >“IDHNQIItNyQ”“日期”= >“2019-10-24”,);//使用默认上下文编码xmlEncoder->编码(数据“xml”);/ /输出://<?xml version = " 1.0 "? >/ /响应> </ / < id > IDHNQIItNyQ id > < // / <日期> 2019-10-24 > < /日期/ / < /响应>//使用修改的上下文进行编码xmlEncoder->编码(数据“xml”, (“xml_root_node_name”= >“跟踪”“encoder_ignored_node_types”=> [\ xml_pi_node, \//删除XML声明(前导XML标记))));/ /输出:/ / <追踪>/ / < id > IDHNQIItNyQ id > < // / <日期> 2019-10-24 > < /日期/ / < /跟踪>

YamlEncoder

这个编码器需要Yaml组件并从Yaml转换到Yaml。

YamlEncoder上下文选项

编码()方法,像其他编码器一样,使用上下文为YamlEncoder设置一个关联数组的配置选项:

1
yamlEncoder->编码(数组yaml的上下文);

以下是可用的选项:

选项 描述 默认的
yaml_inline 切换到内联YAML的级别 0
yaml_indent 压痕级别(内部使用) 0
yaml_flags 有点领域Yaml: DUMP_ */PARSE_ *常量来定制YAML字符串的编码/解码 0

零值

默认情况下,序列化器将保留包含价值。属性可以更改此行为AbstractObjectNormalizer: SKIP_NULL_VALUES上下文选项。真正的

1 2 3 4 5 6 7 8
公共喷火公共酒吧“notNull”;};标准化者ObjectNormalizer ();结果标准化者->正常化(json的, (AbstractObjectNormalizer::SKIP_NULL_VALUES = >真正的]);// ['bar' => 'notNull']

未初始化与默认值不同的状态无类型属性的。当您试图在给出显式值之前访问类型化属性时,会得到一个错误。

为了避免序列化器在序列化或规范化具有未初始化属性的对象时抛出错误,默认情况下,对象规范化器会捕获这些错误并忽略这些属性。

属性可以禁用此行为AbstractObjectNormalizer: SKIP_UNINITIALIZED_VALUES上下文选项。

1 2 3 4 5 6 7 8
公共字符串喷火“初始化”公共字符串酒吧/ /未初始化标准化者ObjectNormalizer ();结果标准化者->正常化(假(),json的, (AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES = >]);//抛出Symfonob娱乐下载y\Component\PropertyAccess\Exception\UninitializedPropertyException,因为规范化器无法读取未初始化的属性

请注意

调用PropertyNormalizer:规范化orgydF4y2BaGetSetMethodNormalizer:规范化AbstractObjectNormalizer: SKIP_UNINITIALIZED_VALUES上下文选项设置为会抛出一个\错误实例,如果给定对象具有未初始化的属性,因为规范化器无法读取它们(直接或通过getter/isser方法)。

5.4

AbstractObjectNormalizer: SKIP_UNINITIALIZED_VALUES常量是在Symfony 5.4中引入的。ob娱乐下载

COLLECT_DENORMALIZATION_ERRORS选项,一次收集所有异常,并使对象部分非正规化:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
试一试dto序列化器->反序列化(请求->getContent (), MyDto::类,json的, [DenormalizerInterface .::COLLECT_DENORMALIZATION_ERRORS = >真正的]);}(PartialDenormalizationExceptione) {违反ConstraintViolationList ();/**@varNotNormalizableValueException $exception */foreache->getErrors ()作为异常) {消息= sprintf (类型必须是"%s" ("%s"给定)之一内爆(”、“异常->getExpectedTypes ()),异常->getCurrentType ());参数= [];如果异常->canUseMessageForUser ()) {参数“提示”] =异常->getMessage ();}违反->add (ConstraintViolation (消息参数异常->getPath (),));}返回->json (违反400);}

5.4

COLLECT_DENORMALIZATION_ERRORS选项在Symfony 5.4中引入。ob娱乐下载

12 34 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
组织私人的名字私人成员公共函数setName的名字->name =的名字;}公共函数getName()返回->名称;}公共函数setMembers(数组成员->成员=成员;}公共函数getMembers()返回->成员;}}成员私人的名字私人组织公共函数setName的名字->name =的名字;}公共函数getName()返回->名称;}公共函数setOrganization(组织组织->组织=组织;}公共函数getOrganization()返回->组织;}}

为了避免无限循环,GetSetMethodNormalizerorgydF4y2BaObjectNormalizer扔一个CircularReferenceException遇到这种情况时:

1 2 3 4 5 6 7 8 9 10
成员成员();成员->setName (“凯文”);组织组织();组织->setName (“Les-Tilleuls.coop”);组织->setMembers ([成员]);成员->setOrganization (组织);回声序列化器->序列化(组织json的);//抛出CircularReferenceException

的关键circular_reference_limit在默认上下文中,设置在将同一对象视为循环引用之前序列化该对象的次数。默认值为1

循环引用也可以由自定义调用对象处理,而不是抛出异常。这在序列化具有唯一标识符的实体时特别有用:

1 2 3 4 5 6 7 8 9 10 11
编码器JsonEncoder ();defaultContext= [AbstractNormalizer .::CIRCULAR_REFERENCE_HANDLER = >函数对象格式上下文返回对象->getName ();});标准化者ObjectNormalizer (defaultContext);序列化器序列化器([标准化者]、[编码器]);var_dump (序列化器->序列化(orgjson的));/ / {" name ": " Les-Tilleuls。coop","members":[{"name":"K\u00e9vin",组织:" Les-Tilleuls.coop"}]}

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
名称空间AcmeMyObj公共喷火/ * * *@var自我* /公共孩子;}使有效MyObj ();使有效->foo =“使”二级MyObj ();二级->foo =“二级”使有效->孩子=二级level3MyObj ();level3->foo =level3的二级->孩子=level3

序列化器可以配置为为给定属性设置最大深度。这里,我们把它设为2美元的孩子属性:

12 3 4 5 6 7 8 9 10 11 12 13
名称空间Acme使用ob娱乐下载组件序列化器注释MaxDepthMyObj/ * * *@MaxDepth(2) * /公共孩子/ /……

为了使用此特性,必须配置与所选格式相对应的元数据加载器。这是在Symfony应用程序中使用Serializer组件时自动完成的。ob娱乐下载使用独立组件时,请参考组文档欧宝官网下载app学习如何做到这一点。

检查只在AbstractObjectNormalizer: ENABLE_MAX_DEPTH键的值设置为真正的.在下面的例子中,第三层没有被序列化,因为它比配置的最大深度2更深。

12 3 4 5 6 7 8 9 10 11 12
结果序列化器->正常化(使有效, (AbstractObjectNormalizer::ENABLE_MAX_DEPTH = >真正的]);/ * $ =结果[“foo”= >“使”,“孩子”= >[“foo”= >“二级”、“孩子”= >['孩子' = > null , ], ], ];* /

自定义可调用对象可以在达到最大深度时执行,而不是抛出异常。这在序列化具有唯一标识符的实体时特别有用:

12 34 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
使用学说常见的注释AnnotationReader使用ob娱乐下载组件序列化器注释MaxDepth使用ob娱乐下载组件序列化器映射工厂ClassMetadataFactory使用ob娱乐下载组件序列化器映射加载程序AnnotationLoader使用ob娱乐下载组件序列化器标准化者AbstractObjectNormalizer使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器喷火公共id/ * * *@MaxDepth(1) * /公共孩子;}使有效Foo ();使有效->id =1二级Foo ();二级->id =2使有效->孩子=二级level3Foo ();level3->id =3.二级->孩子=level3classMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));//所有回调参数都是可选的(你可以省略你不使用的参数)maxDepthHandler函数innerObjectouterObject、字符串attributeName、字符串格式= null,数组上下文= [])返回“/ foo /”innerObject->id;};defaultContext= [AbstractObjectNormalizer .::MAX_DEPTH_HANDLER = >maxDepthHandler,);标准化者ObjectNormalizer (classMetadataFactorydefaultContext);序列化器序列化器([标准化者]);结果序列化器->正常化(使有效, (AbstractObjectNormalizer::ENABLE_MAX_DEPTH = >真正的]);/ * $ =结果[id = > 1, '孩子' = > [id = > 2, '孩子' = > ' / foo / 3 ',),);* /

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
使用Acmeperson1人();person1->setName (“foo”);person1->setAge (99);person1->setSportsman ();person2人();person2->setName (“酒吧”);person2->setAge (33);person2->setSportsman (真正的);= (person1person2];数据序列化器->序列化(json的);/ /数据包含美元[{“名称”:“foo”,“年龄”:99年,“运动员”:假},{“名称”:“酒吧”,“年龄”:33岁的“运动员”:真正}]

如果要反序列化这样的结构,需要添加ArrayDenormalizer归一化函数的集合。通过添加[]属性的类型参数反序列化()方法,您表明您期待的是一个数组而不是单个对象:

12 3 4 5 6 7 8 9 10 11 12
使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器标准化者ArrayDenormalizer使用ob娱乐下载组件序列化器标准化者GetSetMethodNormalizer使用ob娱乐下载组件序列化器序列化器序列化器序列化器([GetSetMethodNormalizer (),ArrayDenormalizer()]、[JsonEncoder ()));数据=……;//前面示例中的序列化数据序列化器->反序列化(数据“Acme \[]的人”json的);

值对象,如果缺少一些参数,序列化器将无法创建对象。在这些情况下,使用default_constructor_arguments上下文选项:

12 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
使用ob娱乐下载组件序列化器标准化者AbstractNormalizer使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器MyObj私人喷火私人酒吧公共函数__construct喷火酒吧->foo =喷火->酒吧=酒吧;}}标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);数据序列化器->denormalize ([“foo”= >“你好”],“MyObj”, (AbstractNormalizer::Default_constructor_arguments => [“MyObj”= > [“foo”= >“酒吧”= >],]]);// $data = new MyObj('Hello', ");

PropertyInfo组件去规范化复杂类型(对象)。类属性的类型将使用提供的提取器进行猜测,并用于递归地反规范化内部数据。

在Symfony应用程序中使用此组件时,所有规范化器都会自动配ob娱乐下载置为使用已注册的提取器。单独使用组件时,的实现PropertyTypeExtractorInterface,通常是…的实例PropertyInfoExtractor参数的第4个参数ObjectNormalizer

12 34 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
名称空间Acme使用ob娱乐下载组件PropertyInfoReflectionExtractor使用ob娱乐下载组件序列化器标准化者DateTimeNormalizer使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器ObjectOuter私人内心的私人日期公共函数捷信()返回->内心的;}公共函数装入的(ObjectInner内心的->内心的=内心的;}公共函数设置当前日期(\ DateTimeInterface日期->日期=日期;}公共函数获取当前日期()返回->日期;}}ObjectInner公共喷火公共酒吧;}标准化者ObjectNormalizer (ReflectionExtractor ());序列化器序列化器([DateTimeNormalizer (),标准化者]);obj序列化器->denormalize ([“内心”= > [“foo”= >“foo”“酒吧”= >“酒吧”],“日期”= >“1988/01/21”],“Acme \ ObjectOuter”);转储(obj->捷信()->foo);/ /“foo”转储(obj->捷信()->栏);/ / '酒吧'转储(obj->获取当前日期()->格式(“Y-m-d”));/ /“1988-01-21”

当一个PropertyTypeExtractor,规格化器还将检查要反规格化的数据是否与属性的类型匹配(即使是基本类型)。例如,如果a字符串,但属性的类型是int,一个UnexpectedValueException会被扔。可以通过设置序列化器上下文选项禁用属性的类型强制ObjectNormalizer: DISABLE_TYPE_ENFORCEMENT真正的

ClassDiscriminatorResolverInterface的实现ObjectNormalizer

的实现ClassDiscriminatorResolverInterface被称为ClassDiscriminatorFromClassMetadata它使用类元数据工厂和映射配置来序列化和反序列化正确类的对象。

在Symfony应用程序中使用此组件时,类元数据工厂已启用,如ob娱乐下载属性组部分,这已经设置好了,你只需要提供配置。否则:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
/ /……使用ob娱乐下载组件序列化器编码器JsonEncoder使用ob娱乐下载组件序列化器映射ClassDiscriminatorFromClassMetadata使用ob娱乐下载组件序列化器映射ClassDiscriminatorMapping使用ob娱乐下载组件序列化器标准化者ObjectNormalizer使用ob娱乐下载组件序列化器序列化器classMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));鉴频器ClassDiscriminatorFromClassMetadata (classMetadataFactory);序列化器序列化器([ObjectNormalizer (classMetadataFactory鉴频器)]、[json的= >JsonEncoder ()));

现在配置标识符类映射。考虑一个定义摘要的应用程序CodeRepository扩展的类GitHubCodeRepository而且BitBucketCodeRepository类:

  • 注释
  • 属性
  • YAML
  • XML
12 3 4 5 6 7 8 9 10 11 12 13 14
名称空间应用程序使用ob娱乐下载组件序列化器注释DiscriminatorMap/ * * *@DiscriminatorMap(typeProperty="type", mapping={* "github"="App\GitHubCodeRepository", * "bitbucket"="App\BitBucketCodeRepository" *}) */摘要CodeRepository/ /……

一旦配置,序列化器使用映射来选择正确的类:

1 2 3 4 5
序列化序列化器->序列化(GitHubCodeRepository (),json的);// {"type": "github"}存储库序列化器->反序列化(序列化, CodeRepository::类,json的);// instanceof githubcoderrepository

另请参阅

Symfony Serializer组件ob娱乐下载的规范化器支持流行的web API格式(JSON-LD, GraphQL, OpenAPI, HAL,JSON: API),可作为API的平台项目。

另请参阅

Symfony Serializer组件的一个流行替代品是ob娱乐下载第三方库,JMS序列化器(版本之前v1.12.0是在Apache许可证下发布的,因此与GPLv2项目不兼容)。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
ob娱乐下载Symfony 5.4支持通过私人Packagist
把代码质量放在项目的核心位置"></a>
          <p class=把代码质量放在项目的核心位置

现在专注于你的代码,其他的由我们来处理"></a>
          <p class=现在专注于你的代码,其他的由我们来处理

检查开发、测试、阶段和生产阶段的代码性能"></a>
          <p class=检查开发、测试、阶段和生产阶段的代码性能