序列化器组件
编辑该页面警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.3,不再维护。
读这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。
序列化器组件
序列化器组件是用来把对象变成一个特定格式(XML、JSON、YAML…)和其它的方法。
为了这样做,序列化器组件遵循以下简单的模式。
正如你所看到的在上面的图片中,一个数组作为男人在中间。这样,编码器将只处理特定的格式成数组反之亦然。同样,标准化者将处理特定的对象成数组反之亦然。
序列化是一个复杂的主题。这个组件可能无法覆盖所有你的用例的盒子,但它可能是有用的开发工具来进行序列化和反序列化对象。
安装
您可以安装组件在两个不同的方面:
- 安装它通过作曲家(
欧宝娱乐app下载地址symfony /序列化器
在Packagist); - 使用官方的Git存储库(https://github.com/欧宝娱乐app下载地址symfony/serializer)。
然后,需要供应商/ 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”);
在这种情况下,反序列化()需要三个参数:
- 是解码的信息
- 这类的名称将解码的信息
- 使用的编码器将这些信息转化为一个数组
3.3
支持allow_extra_attributes
关键是在Symfony 3.3中引入的上下文中。欧宝娱乐app下载地址
默认情况下,附加属性不映射到规范化的对象序列化器组件将被忽略。设置allow_extra_attributes
反序列化上下文的关键假
让序列化器抛出异常时附加属性传递:
1 2 3 4 5 6 7 8 9 10 11 12 13
美元数据=< < < EOF foo <人> <名称> < /名称> <时代> 99 < /年龄> <城市> < /城市> < /人> EOF巴黎;/ /这将抛出一个Symfony \序列化欧宝娱乐app下载地址器\ \组件异常\ ExtraAttributesException/ /因为“城市”不是一个Person类的属性美元人=美元序列化器- >反序列化(美元数据,“Acme \人”,“xml”,数组(“allow_extra_attributes”= >假));
反序列化在现有对象
序列化器也可以用来更新现有的对象:
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”栏:“酒吧”)
选择特定的属性
也可以序列化只有一组特定的属性:
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
使用欧宝娱乐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的);/ /输出:{“名称”:“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,包括GetSetMethodNormalizer和PropertyNormalizer:
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,json的);/ / {“org_name”:“Acme公司。”,“org_address”:“123大街,大城市”}美元objCopy=美元序列化器- >反序列化(美元json、公司::类,json的);/ /相同的数据美元obj
CamelCase, snake_case
在许多格式,通常使用下划线分隔单词(也称为snake_case)。然而,在Symfony应欧宝娱乐app下载地址用程序通常使用(即使CamelCase命名属性PSR-1标准不推荐任何特定的属性名称)。
欧宝娱乐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 ' = > '凯文'];美元安妮=美元标准化者- >