Serializer组件

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 4.1,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

Serializer组件

Serializer组件用于将对象转换为特定的格式(XML、JSON、YAML等),或者将对象转换为特定的格式。

为此,Serializer组件遵循以下模式。

如上图所示,数组被用作对象和序列化内容之间的中介。这样,编码器将只处理特定的转向格式数组反之亦然。同样,Normalizers将处理转向特定对象数组反之亦然。

序列化是一个复杂的主题。这个组件可能无法覆盖您的所有用例,但它对于开发序列化和反序列化对象的工具非常有用。

安装

1
作曲家需要symfony/序列化器欧宝娱乐app下载地址

或者,您可以克隆https://github.com/欧宝娱乐app下载地址symfony/serializer存储库。

请注意

如果在Symfony应用程序外部安装此组件,则必须要求欧宝娱乐app下载地址供应商/ autoload.php文件,以启用Composer提供的类自动加载机制。读这篇文章欲知详情。

使用ObjectNormalizer,PropertyAccess组件也必须安装。

使用

另请参阅

本文解释如何在任何PHP应用程序中使用Serializer特性作为独立组件。读了如何使用序列化器文章,以了解如何在Symfony应用程序中使用它。欧宝娱乐app下载地址

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

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

首选的归一化器是ObjectNormalizer,但其他归一化器是可用的。下面显示的所有示例都使用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 51 52
名称空间应用程序模型私人年龄私人的名字私人运动员私人createdAt/ /读取器公共函数getName()返回->名称;}公共函数getAge()返回->年龄;}公共函数getCreatedAt()返回->createdAt;}/ /伊塞公共函数isSportsperson()返回->纯真的;}/ / setter公共函数setName的名字->name =的名字;}公共函数setAge年龄->年龄=年龄;}公共函数setSportsperson运动员->纯真的=运动员;}公共函数setCreatedAtcreatedAt->createdAt =createdAt;}}

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

1 2 3 4 5 6 7 8 9 10
模型应用\ \人();->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组件忽略。如果希望在发生这种情况时抛出异常,请设置allow_extra_attributes上下文选项。并提供一个实现ClassMetadataFactoryInterface在构造规范化器时:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
数据< < < EOF <人> <名称> foo < /名称> < > 99岁年龄< / > < >城市巴黎城市< / > < > /人EOF;//这将抛出Symfony\Compone欧宝娱乐app下载地址nt\Serializer\Exception\ExtraAttributesException//因为“city”不是Person类的属性classMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);序列化器->反序列化(数据“模型应用\ \人”“xml”, (“allow_extra_attributes”= >]);

在现有对象中反序列化

序列化器也可以用来更新现有对象:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
/ /……人();->setName (“酒吧”);->setAge (99);->setSportsperson (真正的);数据< < < EOF <人> <名称> foo < /名称> < > 69岁年龄< / > < > /人EOF;序列化器->反序列化(数据,人::类,“xml”, (“object_to_populate”= >]);// $person = App\Model\ person(名称:'foo',年龄:'69',sportsperson: true)

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

属性组

有时,您希望序列化来自实体的不同属性集。分组是实现这一需求的便捷方式。

假设你有以下简单的老php对象:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
名称空间AcmeMyObj公共喷火私人酒吧公共函数getBar()返回->酒吧;}公共函数setBar酒吧返回->酒吧=酒吧;}}

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

初始化ClassMetadataFactory像下面这样:

12 3 4 5 6 7 8 9 10 11 12 13 14
使用欧宝娱乐app下载地址组件序列化器映射工厂ClassMetadataFactory//对于注释使用学说常见的注释AnnotationReader使用欧宝娱乐app下载地址组件序列化器映射加载程序AnnotationLoader//用于XML//使用Sym欧宝娱乐app下载地址fony\Component\Serializer\Mapping\Loader\XmlFileLoader;//对于YAML//使用Sym欧宝娱乐app下载地址fony\Component\Serializer\Mapping\Loader\YamlFileLoader;classMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));//用于XML// $classMetadataFactory = new classMetadataFactory (new XmlFileLoader('/path/to/your/ define .xml'));//对于YAML$classMetadataFactory = new classMetadataFactory (new YamlFileLoader('/path/to/your/ define .yaml'));

然后,创建你的组定义:

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

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

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
使用欧宝娱乐app下载地址组件序列化器序列化器使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizerobjMyObj ();obj->foo =“foo”obj->setBar (“酒吧”);标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);数据序列化器->正常化(obj, (“组织”= > [“group1”]]);// $data = ['foo' => 'foo'];methoda序列化器->denormalize ([“foo”= >“foo”“酒吧”= >“酒吧”],“MyObj”, (“组织”= > [“group1”“group3”]]);// $obj2 = MyObj(foo: 'foo', bar: 'bar')

请注意

为了使用注释加载器,您应该安装教义/注释而且教义/缓存使用Composer打包。

提示

注释类不会自动加载,所以你必须像这样使用类加载器加载它们:

1 2 3 4 5 6 7 8 9
使用作曲家自动装载类加载器使用学说常见的注释AnnotationRegistry/**@varClassLoader $loader */加载程序需要__DIR__“/ . . /供应商/ autoload.php”;AnnotationRegistry::registerLoader ([加载程序“loadClass”]);返回加载程序

选择特定属性

也可以只序列化一组特定的属性:

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
使用欧宝娱乐app下载地址组件序列化器序列化器使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer用户公共familyName公共givenName公共公司;}公司公共的名字公共地址;}公司公司();公司->name =“Les-Tilleuls.coop”公司->地址=法国里尔的用户用户();用户->familyName =“Dunglas”用户->givenName =“凯文”用户->公司=公司序列化器序列化器([ObjectNormalizer ()));数据序列化器->正常化(用户, (“属性”= > [“familyName”“公司”= > [“名字”]]]);/ / $ data = [' familyName ' = > ' Dunglas ', '公司' = >['名字' = > ' Les-Tilleuls.coop ']);

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

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

忽略属性

请注意

属性组代替setIgnoredAttributes ()方法被认为是最佳实践。

作为一个选项,有一种方法可以忽略来自源对象的属性。要删除这些属性,请使用setIgnoredAttributes ()方法的规范化定义:

1 2 3 4 5 6 7 8 9 10
使用欧宝娱乐app下载地址组件序列化器序列化器使用欧宝娱乐app下载地址组件序列化器编码器JsonEncoder使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer标准化者ObjectNormalizer ();标准化者->setIgnoredAttributes ([“年龄”]);编码器JsonEncoder ();序列化器序列化器([标准化者]、[编码器]);序列化器->序列化(json的);//输出:{"name":"foo","sportsperson":false}

在序列化和反序列化时转换属性名

有时序列化属性的命名必须与PHP类的属性或getter/setter方法不同。

Serializer组件提供了一种方便的方法来将PHP字段名转换或映射到序列化的名称:名称转换系统。

假设你有以下对象:

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
使用欧宝娱乐app下载地址组件序列化器NameConverterNameConverterInterfaceOrgPrefixNameConverter实现了NameConverterInterface公共函数正常化propertyName返回“org_”propertyName;}公共函数denormalizepropertyName//删除'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
使用欧宝娱乐app下载地址组件序列化器编码器JsonEncoder使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer使用欧宝娱乐app下载地址组件序列化器序列化器nameConverterOrgPrefixNameConverter ();标准化者ObjectNormalizer (nameConverter);序列化器序列化器([标准化者]、[JsonEncoder ()));公司公司();公司->name =“Acme公司”。公司->地址=“大城市主街123号”json序列化器->序列化(公司json的);// {"org_name": "Acme Inc.", "org_address": "大城市主街123号"}companyCopy序列化器->反序列化(json、公司::类,json的);//与$company相同的数据

CamelCase到snake_case

在许多格式中,通常使用下划线分隔单词(也称为snake_case)。然而,在Symfony应欧宝娱乐app下载地址用程序中,通常使用CamelCase来命名属性(尽管PSR-1标准对于属性名不推荐任何特定的情况)。

欧宝娱乐app下载地址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
使用欧宝娱乐app下载地址组件序列化器NameConverterCamelCaseToSnakeCaseNameConverter使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer标准化者ObjectNormalizer (CamelCaseToSnakeCaseNameConverter ());私人firstName公共函数__constructfirstName->firstName =firstName;}公共函数getFirstName()返回->firstName;}}凯文人(“凯文”);标准化者->正常化(凯文);// ['first_name' => 'Kévin'];安妮标准化者->denormalize ([“first_name”= >“安妮”],“人”);// firstName: 'Anne'的Person对象

序列化布尔属性

如果您正在使用isser方法(方法前缀为,就像模型应用\ \人::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
使用应用程序模型使用欧宝娱乐app下载地址组件序列化器编码器JsonEncoder使用欧宝娱乐app下载地址组件序列化器标准化者GetSetMethodNormalizer使用欧宝娱乐app下载地址组件序列化器序列化器编码器JsonEncoder ();标准化者GetSetMethodNormalizer ();回调函数dateTime返回dateTime运算符\ DateTime吗?dateTime->(\ DateTime格式::ISO8601):'';};标准化者->setCallbacks ([“createdAt”= >回调]);序列化器序列化器([标准化者]、[编码器]);人();->setName (“cordoval”);->setAge (34);->setCreatedAt (\ DateTime (“现在”));序列化器->序列化(json的);/ /输出:{“名称”:“cordoval”,“年龄”:34岁“createdAt”:“2014 - 03 - 22 - t09:43:12 - 0500 "}

标准化者

有几种类型的归一化器可用:

ObjectNormalizer

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

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

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

GetSetMethodNormalizer

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

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

PropertyNormalizer

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

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

JsonSerializableNormalizer

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

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

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

json_encode可以处理循环引用。

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

此规范化器转换实现的对象ConstraintViolationListInterface的错误列表RFC 7807标准。

4.1

ConstraintViolationListNormalizer在Symfony 4.1中引入。欧宝娱乐app下载地址

编码器

编码器将数组格式反之亦然。它们实现EncoderInterface用于编码(数组格式化)和DecoderInterface用于解码(格式到数组)。

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

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

内置编码器

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

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

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

JsonEncoder

JsonEncoder编码和解码JSON字符串,基于PHPjson_encode而且json_decode功能。

CsvEncoder

CsvEncoder编码到CSV并从CSV解码。

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

4.1

as_collection选项在Symfony 4.1中引入。欧宝娱乐app下载地址

XmlEncoder

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

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

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

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

1 2 3 4 5 6
<?xml version =“1.0”? ><回答> < foo >1< / foo > < foo >2> < / foo > <酒吧1< /酒吧> < /响应>

请注意,此编码器将考虑以@属性:

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

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

4.1

as_collection选项在Symfony 4.1中引入。欧宝娱乐app下载地址

提示

在解码内容时,默认情况下忽略XML注释,但是可以通过可选选项更改此行为ignoredNodeTypes美元的参数XmlEncoder类的构造函数。

4.1

从Symfony 4.1开始,默认情况下忽略XML注释。欧宝娱乐app下载地址

YamlEncoder

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

处理循环引用

循环引用在处理实体关系时很常见:

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

setCircularReferenceLimit ()方法设置在将同一对象视为循环引用之前序列化该对象的次数。默认值为1

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

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

处理序列化深度

Serializer组件能够检测和限制序列化深度。它在序列化大型树时特别有用。假设数据结构如下:

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美元的孩子属性:

  • 注释
  • YAML
  • XML
12 3 4 5 6 7 8 9 10 11 12 13
使用欧宝娱乐app下载地址组件序列化器注释MaxDepth名称空间AcmeMyObj/ * * *@MaxDepth(2) * /公共孩子/ /……

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

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

12 3 4 5 6 7 8 9 10 11 12
结果序列化器->正常化(使有效, (“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
使用学说常见的注释AnnotationReader使用欧宝娱乐app下载地址组件序列化器序列化器使用欧宝娱乐app下载地址组件序列化器注释MaxDepth使用欧宝娱乐app下载地址组件序列化器映射工厂ClassMetadataFactory使用欧宝娱乐app下载地址组件序列化器映射加载程序AnnotationLoader使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer喷火公共id/ * * *@MaxDepth(1) * /公共孩子;}使有效Foo ();使有效->id =1二级Foo ();二级->id =2使有效->孩子=二级level3Foo ();level3->id =3.二级->孩子=level3classMetadataFactoryClassMetadataFactory (AnnotationLoader (AnnotationReader ()));标准化者ObjectNormalizer (classMetadataFactory);标准化者->setMaxDepthHandler (函数喷火返回“/ foo /”喷火->id;});序列化器序列化器([标准化者]);结果序列化器->正常化(使有效, (ObjectNormalizer::ENABLE_MAX_DEPTH = >真正的]);/ * $ =结果[id = > 1, '孩子' = > [id = > 2, '孩子' = > ' / foo / 3 ',),);* /

4.1

setMaxDepthHandler ()方法是在Symfony 4.1中引入的。欧宝娱乐app下载地址

处理数组

Serializer组件也能够处理对象数组。序列化数组就像序列化单个对象一样:

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
使用欧宝娱乐app下载地址组件序列化器编码器JsonEncoder使用欧宝娱乐app下载地址组件序列化器标准化者ArrayDenormalizer使用欧宝娱乐app下载地址组件序列化器标准化者GetSetMethodNormalizer使用欧宝娱乐app下载地址组件序列化器序列化器序列化器序列化器([GetSetMethodNormalizer (),ArrayDenormalizer()]、[JsonEncoder ()));数据=……;//前面示例中的序列化数据序列化器->反序列化(数据“Acme \[]的人”json的);

XmlEncoder

这个编码器将数组转换为XML,反之亦然。例如,取一个对象,规范化如下:

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

XmlEncoder对该对象进行如下编码:

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

数组键以@被视为XML属性:

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

使用特惠键定义节点数据:

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

上下文

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

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

以下是可用的选项:

xml_format_output
如果设置为true,则使用换行和缩进格式化生成的XML。
xml_version
设置XML版本属性(默认值:1.1).
xml_encoding
设置XML编码属性(默认值:utf - 8).
xml_standalone
在生成的XML中添加独立属性(默认:真正的).
xml_root_node_name
设置根节点名称(默认为:响应).
remove_empty_tags
如果设置为true,则删除生成的XML中的所有空标记。

处理构造函数参数

4.1

default_constructor_arguments选项在Symfony 4.1中引入。欧宝娱乐app下载地址

如果类构造函数定义了参数,就像通常发生在值对象,如果缺少一些参数,序列化器将无法创建对象。在这些情况下,使用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
使用欧宝娱乐app下载地址组件序列化器序列化器使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizerMyObj私人喷火私人酒吧公共函数__construct喷火酒吧->foo =喷火->酒吧=酒吧;}}标准化者ObjectNormalizer (classMetadataFactory);序列化器序列化器([标准化者]);数据序列化器->denormalize ([“foo”= >“你好”],“MyObj”, (“default_constructor_arguments”= > [“MyObj”= > [“foo”= >''“酒吧”= >''],]]);// $data = new MyObj('Hello', ");

递归去正规化和类型安全

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

在Symfony应用程序中使用此组件时,所有规范化器都会自动配欧宝娱乐app下载地址置为使用已注册的提取器。单独使用组件时,的实现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
使用欧宝娱乐app下载地址组件PropertyInfoReflectionExtractor使用欧宝娱乐app下载地址组件序列化器序列化器使用欧宝娱乐app下载地址组件序列化器标准化者DateTimeNormalizer使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer名称空间AcmeObjectOuter私人内心的私人日期公共函数捷信()返回->内心的;}公共函数装入的(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真正的

序列化接口和抽象类

当处理非常相似或共享属性的对象时,您可以使用接口或抽象类。Serializer组件允许您使用对象序列化和反序列化这些对象“鉴别器类映射”

鉴别器是用于区分可能的对象的字段(在序列化的字符串中)。在实践中,当使用Serializer组件时,传递一个ClassDiscriminatorResolverInterface的实现ObjectNormalizer

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

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

12 3 4 5 6 7 8 9 10 11 12 13 14 15
/ /……使用欧宝娱乐app下载地址组件序列化器编码器JsonEncoder使用欧宝娱乐app下载地址组件序列化器映射ClassDiscriminatorMapping使用欧宝娱乐app下载地址组件序列化器映射ClassDiscriminatorFromClassMetadata使用欧宝娱乐app下载地址组件序列化器标准化者ObjectNormalizer使用欧宝娱乐app下载地址组件序列化器序列化器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
名称空间应用程序使用欧宝娱乐app下载地址组件序列化器注释DiscriminatorMap/ * * *@DiscriminatorMap(typeProperty="type", mapping={* "github"="App\GitHubCodeRepository", * "bitbucket"="App\BitBucketCodeRepository" *}) */接口CodeRepository/ /……

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

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

性能

要确定必须使用哪个规范化器(或反规范化器)来处理对象,请使用序列化器类将调用supportsNormalization ()(或supportsDenormalization ()循环中所有已注册的归一化器(或非归一化器)。

这些方法的结果取决于要序列化的对象、格式和上下文。这就是这个结果的原因不是缓存的默认情况下,会导致严重的性能瓶颈。

然而,当对象的类型和格式相同时,大多数规范化器(和反规范化器)总是返回相同的结果,因此结果可以被缓存。方法的规范化(和反规范化)实现CacheableSupportsMethodInterface并返回真正的hasCacheableSupportsMethod ()被称为。

请注意

所有内置归一化和非归一化包括在API的平台本机实现此接口。

了解更多

另请参阅

Symfony Serializer组件欧宝娱乐app下载地址的规范化器支持流行的web API格式(JSON-LD, GraphQL, HAL和JSONAPI)API的平台项目。

另请参阅

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

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。