如何使用序列化(Serializer)


一个对象和不同格式(比如JSON或XML)之间的序列化和反序列化是一个非常复杂的话题。Symfony自带了一个 Serializer组件,给你提供了一些工具,可以随需利用。

实际上,在你开始使用之前,先熟悉一下serializer,normalizer和encoder,阅读 Serializer组件 一文。

激活Serializer 

serializer 服务默认不可用。要开启它,在你的配置文件中激活它:serializer 服务默认不可用。要开启它,在你的配置文件中激活它:

PHP:// app/config/config.php$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'enabled' => true,
    ),));
XML:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:framework="http://symfony.com/schema/dic/symfony"    xmlns:twig="http://symfony.com/schema/dic/twig"    xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/symfony        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd        http://symfony.com/schema/dic/twig        http://symfony.com/schema/dic/twig/twig-1.0.xsd">
    <framework:config>
        <!-- ... -->
        <framework:serializer enabled="true" />
    </framework:config></container>
YAML:# app/config/config.ymlframework:    # ...
    serializer:
        enabled: true

使用Serializer服务 

一旦开启, serializer 服务可以在你需要它时注入到任何服务中,或者像下面这样在控制器中使用:

// src/AppBundle/Controller/DefaultController.phpnamespace AppBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class DefaultController extends Controller{
    public function indexAction()
    {
        $serializer = $this->get('serializer');         // ...
    }}

添加Normalizers和Encoders 

被开启之后, serializer 在容器中可用,被加载时还带有两个 encodersJsonEncoderXmlEncoder)以及ObjectNormalizer normalizer

你可以加载normalizers和/或encoders,只要给它们打上 serializer.normalizerserializer.encoder 标签。也可以设置标签的优先级,以便决定匹配顺序。

下例演示了如何加载 GetSetMethodNormalizer

PHP:// app/config/services.phpuse Symfony\Component\DependencyInjection\Definition; $definition = new Definition(
    'Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer'));$definition->setPublic(false);$definition->addTag('serializer.normalizer');$container->setDefinition('get_set_method_normalizer', $definition);
XML:<!-- app/config/services.xml --><services>
    <service id="get_set_method_normalizer" class="Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer" public="false">
        <tag name="serializer.normalizer" />
    </service></services>

YAML:# app/config/services.ymlservices:
    get_set_method_normalizer:
        class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer
        public: false
        tags:
            - { name: serializer.normalizer }
使用Serializer服务 ¶🎜🎜🎜一旦开启, serializer 服务可以在你需要它时注入到任何服务中,或者像下面这样在控制器中使用:🎜
PHP:// app/config/config.php$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'enable_annotations' => true,
    ),));
🎜添加Normalizers和Encoders 
¶🎜🎜🎜🎜被开启之后, serializer 在容器中可用,被加载时还带有两个 🎜encoders🎜(JsonEncoder🎜XmlEncoder🎜)以及🎜ObjectNormalizer normalizer🎜。🎜🎜你可以加载normalizers和/或encoders,只要给它们打上 serializer.normalizer🎜 和 serializer.encoder🎜 标签。也可以设置标签的优先级,以便决定匹配顺序。🎜🎜下例演示了如何加载 GetSetMethodNormalizer🎜:🎜
XML:<!-- app/config/config.xml --><framework:config>
    <!-- ... -->
    <framework:serializer enable-annotations="true" /></framework:config>
YAML:# app/config/config.ymlframework:    # ...
    serializer:
        enable_annotations: true
🎜
$serializer = $this->get('serializer');$json = $serializer->serialize(
    $someObject,
    'json', array('groups' => array('group1')));
🎜

使用序列化的群组Annotations 

通过以下配置来开启 序列化群组注释

PHP:// app/config/config_prod.php$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'cache' => 'serializer.mapping.cache.apc',
    ),));
XML:<!-- app/config/config_prod.xml --><framework:config>
    <!-- ... -->
    <framework:serializer cache="serializer.mapping.cache.apc" /></framework:config>
YAML:# app/config/config_prod.ymlframework:    # ...
    serializer:
        cache: serializer.mapping.cache.apc

接下来,添加 @Goups annotations 到你的类中,然后在序列化时,选择要使用哪个群组:

PHP:// app/config/config.php$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'name_converter' => 'serializer.name_converter.camel_case_to_snake_case,
    ),
));

除了  @Groups  注释,serializer组件还支持Yaml或Xml文件。这些组件在存放于以下位置时将被自动加载:@Groups  注释,serializer组件还支持Yaml或Xml文件。这些组件在存放于以下位置时将被自动加载:

  • 存放在bundle下面的  Resources/config/  目录中的  serialization.yml  或  serialization.xml

  • 存放在bundle下面的  Resources/config/serialization/  目录中的所有  *.yml  和  *.xml

开启Metadata缓存 

被Serializer组件所使用的metadata,诸如groups,可以被缓存,以提升程序性能。任何实现了 DoctrineCommonCacheCache 接口的服务都可以被使用。

一个利用了 APCu 的服务被内置在框架中:

XML:<!-- app/config/config.xml --><framework:config>
    <!-- ... -->
    <framework:serializer name-converter="serializer.name_converter.camel_case_to_snake_case" /></framework:config>
YAML:# app/config/config.ymlframework:    # ...
    serializer:
        name_converter: 'serializer.name_converter.camel_case_to_snake_case'
rrreee

开启一个命名转换器 

2.8 name_converter  选项从Symfony 2.8开始被引入。

要使用 name converter服务,可以在配置文件中使用 name_converter选项进行定义。

内置的 CamelCase to snake_case name converter(驼峰转蛇型转换器)可以通过设置 serializer.name_converter.camel_case_to_snake_case

  • 存放在bundle下面的  Resources/config/  目录中的  serialization.yml  或  serialization.xml
  • 🎜存放在bundle下面的  Resources/config/serialization/  目录中的所有  *.yml  和  *.xml 。🎜
🎜开启Metadata缓存 ¶🎜🎜🎜被Serializer组件所使用的metadata,诸如groups,可以被缓存,以提升程序性能。任何实现了 DoctrineCommonCacheCache 接口的服务都可以被使用。🎜🎜一个利用了 APCu🎜 的服务被内置在框架中:🎜rrreeerrreeerrreee🎜开启一个命名转换器 ¶🎜🎜
🎜2.8 name_converter  选项从Symfony 2.8开始被引入。🎜🎜🎜要使用 name converter🎜服务,可以在配置文件中使用 name_converter🎜选项进行定义。🎜🎜内置的 CamelCase to snake_case name converter🎜(驼峰转蛇型转换器)可以通过设置 serializer.name_converter.camel_case_to_snake_case 选项值来开启:🎜rrreeerrreee🎜rrreee🎜

深入Serializer 

ApiPlatform 提供了一个API系统,它支持 JSON-LDHydra Core Vocabulary hypermedia格式。它是基于Symfony框架和Serializer组件而构建的。它提供了自定义的normalizers,一个自定义的encoder,自定义的metadata以及一个缓存系统。

如果你希望利用好Symfony Serializer组件的全部威力,应该看一看这个bundle是如何工作的。