WARNING: You are browsing the documentation for Symfony 2.8 which is not maintained anymore. Consider upgrading your projects to Symfony 4.2.

How to Create your Custom Normalizer

2.8 version
Maintained Unmaintained
4.1

How to Create your Custom Normalizer

The Serializer component uses normalizers to transform any data into an array. The component provides several built-in normalizers but you may need to create your own normalizer to transform an unsupported data structure.

Creating a New Normalizer

Imagine you want add, modify, or remove some properties during the serialization process. For that you'll have to create your own normalizer. But it's usually preferable to let Symfony normalize the object, then hook into the normalization to customize the normalized data. To do that, leverage the 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
namespace AppBundle\Serializer;

use AppBundle\Entity\Topic;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class TopicNormalizer implements NormalizerInterface
{
    private $router;
    private $normalizer;

    public function __construct(UrlGeneratorInterface $router, ObjectNormalizer $normalizer)
    {
        $this->router = $router;
        $this->normalizer = $normalizer;
    }

    public function normalize($topic, $format = null, array $context = array())
    {
        $data = $this->normalizer->normalize($topic, $format, $context);

        // Here, add, edit, or delete some data:
        $data['href']['self'] = $this->router->generate('topic_show', array(
            'id' => $topic->getId(),
        ), UrlGeneratorInterface::ABSOLUTE_URL);

        return $data;
    }

    public function supportsNormalization($data, $format = null)
    {
        return $data instanceof Topic;
    }
}

Registering it in Your Application

In order to enable the normalizer in an application based on the entire Symfony framework, you must register it as a service and tag it with serializer.normalizer.

  • YAML
    1
    2
    3
    4
    5
    6
    # app/config/services.yml
    services:
        app.yaml_encoder:
            class: AppBundle\Serializer\TopicNormalizer
            tags:
                - { name: serializer.normalizer }
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <!-- app/config/services.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"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <services>
            <service id="app.yaml_encoder" class="AppBundle\Serializer\TopicNormalizer">
                <tag name="serializer.normalizer" />
            </service>
        </services>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    // app/config/services.php
    use AppBundle\Serializer\TopicNormalizer;
    
    $container
        ->register('app.yaml_encoder', TopicNormalizer::class)
        ->addTag('serializer.normalizer')
    ;
    

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.