skip to Main Content

I have a Tags model (not an entity) with a child Tag model array property.

class Tags
{
    private array $tags;

    public function addTag(Tag $tag): bool{}

    public function removeTag(Tag $tag): bool{}

    public function setTags(array $tags): self{}

    public function getTags(): array{}

And it was correctly serialized.

{
    "tags": [
        {
            "slug": "a_tag",
            "name": "A Tag",
            "description": "This is a nice tag!"
        }
    ]
}

To deserialize I do:

use SymfonyComponentPropertyInfoExtractorReflectionExtractor;
use SymfonyComponentSerializerEncoderJsonEncode;
use SymfonyComponentSerializerEncoderJsonEncoder;
use SymfonyComponentSerializerNormalizerObjectNormalizer;
use SymfonyComponentSerializerSerializer;


        $json = file_get_contents($this->fileName);
        $encoders = [new JsonEncoder()];
        $normalizers = [new ObjectNormalizer(null, null, null, new ReflectionExtractor())];
        $serializer = new Serializer($normalizers, $encoders);

        return $serializer->deserialize($json, Tags::class, 'json');

But when I try to deserialize, I get an error:

The type of the "tags" attribute for class "AppModelTags" must be
one of "AppModelTag[]" ("array" given).

This doesn’t even make sense. It’s not possible to type an array in PHP, so why it’s giving this error?

I think this is somewhat related to Recursive Denormalization and Type Safety, but I don’t get how to fix it.

Thanks in advance

2

Answers


  1. Chosen as BEST ANSWER

    You need to use use an ArrayDenormalizer.

    use SymfonyComponentSerializerNormalizerArrayDenormalizer;
    
            $json = file_get_contents($this->fileName);
    
            $encoders = [new JsonEncoder()];
            $normalizers = [
                new ArrayDenormalizer(),
                new ObjectNormalizer(null, null, null, new ReflectionExtractor())
            ];
            $serializer = new Serializer($normalizers, $encoders);
    
            return $serializer->deserialize($json, Tags::class, 'json');
    

  2. Try this configuration in Symfony yaml config.

    services:
      property_normalizer:
        class: SymfonyComponentSerializerNormalizerPropertyNormalizer
        tags: [ serializer.normalizer ]
        arguments:
          $propertyTypeExtractor: '@SymfonyComponentPropertyInfoPropertyDescriptionExtractorInterface'
      object_normalizer:
        class: SymfonyComponentSerializerNormalizerObjectNormalizer
        tags: [ serializer.normalizer ]
      get_set_method_normalizer:
        class: SymfonyComponentSerializerNormalizerGetSetMethodNormalizer
        tags: [ serializer.normalizer ]
      array_denormalizer:
        class: SymfonyComponentSerializerNormalizerArrayDenormalizer
        tags: [ serializer.denormalizer ]
    

    It works good with collections.

        /**
         * @var Tag[] Tags
         */
        #[OAProperty(type: 'array', items: new OAItems(ref: '#/components/schemas/Tag'))]
        #[AssertValid(traverse: true)]
        protected array $tags;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search