PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, February 16, 2022

[FIXED] How to configure Normalizer with injected SerializerInterface

 February 16, 2022     php, symfony     No comments   

Issue

I know that I can use and configure e.g. the DateTimeNormalizer of Symfony's Serializer like that:

$serializer = new Serializer(array(new DateTimeNormalizer()));

$dateAsString = $serializer->normalize(
    new \DateTime('2016/01/01'),
    null,
    array(DateTimeNormalizer::FORMAT_KEY => 'Y/m')
);
// $dateAsString = '2016/01';

But if I want to use the Serializer without instantiation but with the "full Symfony app" Dependency injection instead like:

//class MyService...

public function __construct(SerializerInterface $serializer)
{
    $this->serializer = $serializer;
}

//function MyFunction()
{
 $json = $this->serializer->serialize($object, 'json');
}

it already comes with the most common Normalizers in a pre-ordered fashion.

Usually this is perfectly fine for my purpose.

But how could I e.g. configure the DateTimeNormalizer::FORMAT_KEY in the injection scenario without creating CustomNormalizers or lots of instantiating?


Solution

I just finished a sprint of my project with a similar problem.

If you only want to format by default you DateTime object, you can add those lines in your config file:

services:
   serializer.normalizer.datetime:
       class: ‘Symfony\Component\Serializer\Normalizer\DateTimeNormalizer
       arguments
           -
               !php/const Symfony\Component\Serializer\Normalizer\DateTimeNormalizer::FORMAT_KEY: 'Y-m-d\TH:i:s.uP’
       tags:
           - { name: serializer.normalizer, priority: -910 }

But in case you want more flexibility and control over the serializer, i advise you to not modify config file but try this following method :

So for my needs, i finally create a MainController that extends AbstractController and each of my controllers extends MainController.

In the MainController I instanciate the serializer as property, so that you can access serializer already configured in the MainControlle by $this->serializer.

MainController :

class MainController extends AbstractController {
    protected $serializer;

    public function __construct() {
        $encoders = [new XmlEncoder(), new JsonEncoder()];
        $normalizers = [
            new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => "your date format"]),
            new ObjectNormalizer()
        ];

        $this->serializer = new Serializer($normalizers, $encoders);
    }
}

PostController :

class PostController extends MainController {

    /**
    * @Route("/posts")
    **/
    public function listPosts() {

        $e = new Entity();

        return $this->serializer->serialize($e, "json");
    }
}

EDIT : !! I forgot to say, be careful to the order you arrange normalizer in instanciation. As DateTime is an object, the serializer will try to normalize the DateTime object with ObjectNormalizer first if ObjectNormalizer is added first (which is used to normalize entities) and will return an empty array.



Answered By - Esteban MANSART
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing