序列化器组件

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.1,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

序列化器组件

序列化器组件是用来把对象变成一个特定格式(XML、JSON、YAML…)和其它的方法。

为了这样做,序列化器组件遵循以下简单的模式。

正如你所看到的在上面的图片中,一个数组作为男人在中间。这样,编码器将只处理特定的格式数组反之亦然。同样,标准化者将处理特定的对象数组反之亦然。

序列化是一个复杂的话题,虽然这个组件可能不工作在所有情况下,它可以是一个有用的工具在开发工具来进行序列化和反序列化对象。

安装

您可以安装组件在两个不同的方面:

然后,需要供应商/ autoload.php文件,使作曲家提供的半自动的机制。否则,您的应用程序无法找到这个Symfony组件的类。欧宝娱乐app下载地址

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

使用

使用序列化器组件是很简单的。你只需要设置序列化器指定编码器和标准化者可用:

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

首选的标准化者ObjectNormalizer,但其它标准化者是可用的。以下所有的示例使用ObjectNormalizer

序列化一个对象

为了这个例子中,假定下面的类已经存在于您的项目:

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 30 31 32 33 34 35 36 37 38 39 40 41
名称空间Acme;{私人美元年龄;私人美元的名字;私人美元运动员;/ /读取器公共函数getName(){返回美元- >名称;}公共函数getAge(){返回美元- >年龄;}/ /伊塞公共函数isSportsman(){返回美元- >运动员;}/ / setter公共函数setName(美元的名字){美元- >name =美元的名字;}公共函数setAge(美元年龄){美元- >年龄=美元年龄;}公共函数setSportsman(美元运动员){美元- >运动员=美元运动员;}}

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

1 2 3 4 5 6 7 8 9 10
美元=Acme \人();美元- >setName (“foo”);美元- >setAge (99年);美元- >setSportsman ();美元jsonContent=美元序列化器- >序列化(美元,json的);/ / $ jsonContent包含{“名称”:“foo”,“年龄”:99年,“运动员”:假}回声美元jsonContent;/ /或返回一个响应

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

反序列化一个对象

你现在学习如何做完全相反。这一次,信息的类将在XML格式编码:

1 2 3 4 5 6 7 8 9 10 11
使用Acme\;美元数据=< < < EOF foo <人> <名称> < /名称> <时代> 99 < /年龄> <运动员>假< /运动员> < /人> EOF;美元=美元序列化器- >反序列化(美元数据,人::类,“xml”);

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

  1. 是解码的信息
  2. 这类的名称将解码的信息
  3. 使用的编码器将这些信息转化为一个数组

反序列化在现有对象

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/ /……美元=人();美元- >setName (“酒吧”);美元- >setAge (99年);美元- >setSportsman (真正的);美元数据=< < < EOF foo <人> <名称> < /名称> <时代> 69 < /年龄> < /人> EOF;美元序列化器- >反序列化(美元数据,人::类,“xml”,数组(“object_to_populate”= >美元));/ / $ = Acme \人(名字:“foo”,年龄:69年,运动员:真正的)

这是一个常见的需要在处理一个ORM。

属性组

有时候,你想要序列化不同实体的属性。组织是实现这一目标需要一个方便的方法。

假设您有以下plain-old-PHP对象:

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

可以使用注释指定序列化的定义,XML或YAML。的ClassMetadataFactory将使用的标准化者必须意识到要使用的格式。

初始化ClassMetadataFactory如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
使用欧宝娱乐app下载地址\组件\序列化器\映射\工厂\ClassMetadataFactory;/ /注释使用学说\常见的\注释\AnnotationReader;使用欧宝娱乐app下载地址\组件\序列化器\映射\加载程序\AnnotationLoader;/ /为XML/ /使用Sy欧宝娱乐app下载地址mfony \组件\序列化器\ \程序\ XmlFileLoader映射;/ / YAML/ /使用Sy欧宝娱乐app下载地址mfony \组件\序列化器\ \程序\ YamlFileLoader映射;美元classMetadataFactory=ClassMetadataFactory (AnnotationLoader (AnnotationReader ()));/ /为XML/ /美元classMetadataFactory = new classMetadataFactory(新XmlFileLoader (' / path / /你/ definition.xml '));/ / YAML/ /美元classMetadataFactory = new classMetadataFactory(新YamlFileLoader (' / path / /你/ definition.yml '));

然后,创建你的组定义:

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

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

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

忽略属性

请注意

使用属性组,而不是setIgnoredAttributes ()方法被认为是最佳实践。

作为一个选项,有一种无视属性从原点对象。删除那些属性使用setIgnoredAttributes ()方法标准化者定义:

1 2 3 4 5 6 7 8 9 10
使用欧宝娱乐app下载地址\组件\序列化器\序列化器;使用欧宝娱乐app下载地址\组件\序列化器\编码器\JsonEncoder;使用欧宝娱乐app下载地址\组件\序列化器\标准化者\ObjectNormalizer;美元标准化者=ObjectNormalizer ();美元标准化者- >setIgnoredAttributes (数组(“年龄”));美元编码器=JsonEncoder ();美元序列化器=序列化器(数组(美元标准化者),数组(美元编码器));美元序列化器- >序列化(美元,json的);/ /输出:{“名称”:“foo”、“运动员”:假}

将属性名当序列化和反序列化

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

序列化器组件提供了一个方便的方法来翻译或PHP字段名称映射到序列化的名字:变频器系统的名称。

给你有以下对象:

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

在序列化形式,必须前缀的所有属性org_如下:

1
{“org_name”:“Acme公司。”,“org_address”:“123大街,大城市”}

自定义名字转换器可以处理这种情况下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
使用欧宝娱乐app下载地址\组件\序列化器\NameConverter\NameConverterInterface;OrgPrefixNameConverter实现了NameConverterInterface{公共函数正常化(美元propertyName){返回“org_”美元propertyName;}公共函数denormalize(美元propertyName){/ /删除org_前缀返回“org_”= = = substr (美元propertyName,0,4)?substr (美元propertyName,4):美元propertyName;}}

自定义标准化者可以通过使用它作为第二个参数的类扩展AbstractNormalizer,包括GetSetMethodNormalizerPropertyNormalizer:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
使用欧宝娱乐app下载地址\组件\序列化器\编码器\JsonEncoder使用欧宝娱乐app下载地址\组件\序列化器\标准化者\ObjectNormalizer;使用欧宝娱乐app下载地址\组件\序列化器\序列化器;美元nameConverter=OrgPrefixNameConverter ();美元标准化者=ObjectNormalizer (,美元nameConverter);美元序列化器=序列化器(数组(美元标准化者),数组(JsonEncoder ()));美元obj=公司();美元obj- >name =“Acme公司”。;美元obj- >地址=123大街,大城市的;美元json=美元序列化器- >序列化(美元obj);/ / {“org_name”:“Acme公司。”,“org_address”:“123大街,大城市”}美元objCopy=美元序列化器- >反序列化(美元json);/ /相同的数据美元obj

CamelCase, snake_case

在许多格式,通常使用下划线分隔单词(也称为snake_case)。然而,PSR-1指定PHP的首选样式属性和方法是CamelCase。

欧宝娱乐app下载地址Symfony提供了一个内置的名字转换器设计之间变换snake_case和CamelCased风格在序列化和反序列化过程:

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

序列化布尔属性

如果您使用的是伊塞方法(前缀的方法,就像Acme \人::isSportsman ()),序列化器组件会自动检测和使用它来序列化相关属性。

ObjectNormalizer还负责方法入手,添加删除

使用回调函数来序列化属性与对象实例

序列化时,你可以设置一个回调格式特定对象属性:

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
使用Acme\;使用欧宝娱乐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,蛇和消毒剂。它支持反规范化过程中调用构造函数。

对象是规范化的地图属性名(方法名的“获得”/“设置”/“”/“删除”前缀和转换为小写)属性值。

ObjectNormalizer是最强大的标准化者。默认配置时使用Symfony的标准版的序列化器启用。欧宝娱乐app下载地址

GetSetMethodNormalizer

这类标准化者读取的内容通过调用“getter”(公共方法从“获得”)。应该将正规化数据通过调用构造函数和“setter”(公共方法从“设置”)。

对象是规范化属性名称的地图(方法名被“获得”的前缀和转换为小写)属性值。

PropertyNormalizer

这种标准化者直接读写以及公共属性私有和保护属性。它支持反规范化过程中调用构造函数。

对象是规范化的地图属性名称属性值。

JsonSerializableNormalizer

这与类,实现标准化者工作JsonSerializable

它将调用JsonSerializable: jsonSerialize ()方法,然后进一步正常化的结果。这意味着,嵌套JsonSerializable类也将归一化。

标准化者是特别有用,当你想要逐渐从现有代码库使用简单的迁移json_encode的Symfon欧宝娱乐app下载地址y序列化器允许您混合标准化者用于哪些类。

json_encode可以处理循环引用。

DateTimeNormalizer
这个标准化者转换DateTimeInterface对象(如。DateTimeDateTimeImmutable)字符串。在默认情况下它使用RFC3339格式。
DataUriNormalizer
这个标准化者转换SplFileInfo对象到一个数据URI字符串(数据:……),这样文件可以嵌入到序列化数据。
. .versionadded:: 3.1
JsonSerializableNormalizer,DateTimeNormalizerDataUriNormalizer标准化者在Symfony 3.1中添加欧宝娱乐app下载地址

处理循环引用

循环引用是常见的在处理实体关系:

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 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(){返回美元- >组织;}}

为了避免无限循环,GetSetMethodNormalizer抛出一个CircularReferenceException当遇到这种情况:

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

setCircularReferenceLimit ()方法的标准化者设置的次数将序列化相同的对象在考虑前一个循环引用。它的默认值是1

而不是抛出异常,循环引用也可以由自定义可调用的。这是特别有用,当序列化实体拥有独特的标识符:

1 2 3 4 5 6 7 8 9 10
美元编码器=JsonEncoder ();美元标准化者=ObjectNormalizer ();美元标准化者- >setCircularReferenceHandler (函数(美元对象){返回美元对象- >getName ();});美元序列化器=序列化器(数组(美元标准化者),数组(美元编码器));var_dump (美元序列化器- >序列化(美元org,json的));/ / {" name ": " Les-Tilleuls。鸡笼”、“成员”:[{“名称”:“K \ u00e9vin”,组织:“Les-Tilleuls.coop”}]}

处理序列化深度

序列化器组件能够检测和限制序列化深度。它序列化大树时尤其有用。假设以下数据结构:

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

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

  • 注释
  • YAML
  • XML
1 2 3 4 5 6 7 8 9 10 11 12 13
使用欧宝娱乐app下载地址\组件\序列化器\注释\MaxDepth;名称空间Acme;MyObj{/ * * *@MaxDepth(2)* /公共美元喷火;/ /……}

相对应的元数据加载器选择格式必须配置以使用此功能。它是使用Symfony的标准版时自动完成。欧宝娱乐app下载地址当使用独立的组件,请参阅组的文档欧宝体育电话学习如何做到这一点。

检查只是如果enable_max_depth关键的序列化器上下文设置真正的。在下面的例子中,第三层次不是序列化的,因为它是比2的配置的最大深度:

1 2 3 4 5 6 7 8 9 10 11 12
美元结果=美元序列化器- >正常化(美元使有效,,数组(“enable_max_depth”= >真正的));/ * $ =结果数组(“foo”= >“使”,“孩子”= >数组(“foo”= >“二级”、“孩子”= >数组(“孩子”= > null,)),);* /

处理数组

对象的序列化器组件能够处理数组。工作就像序列化一个对象序列化数组:

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

如果你想反序列化这样的结构,你需要添加ArrayDenormalizer标准化者的集合。通过添加[]的类型参数反序列化()方法,表明你期待一个数组而不是一个对象。

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

了解更多

另请参阅

一个受欢迎的选择Symfony序列化器组件是第三方库,欧宝娱乐app下载地址JMS序列化器(在Apache许可下发布的,因此不符合GPLv2项目)。

这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。