Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

symfony deserialize nested objects

I have used the Symfony serializer to serialize my Recherche object. In a Recherche object, I have sub objects : Categorie and Lieu.

When I deserialize my Recherche object, all the sub objects are transformed in arrays. I would like them to be objects again.

This is how I have serialized my object:

$encoders = array(new JsonEncoder());
$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(array('parent', 'enfants'));
$normalizer->setCircularReferenceHandler(function ($object) {
    return $object->getCode();
});
$normalizers = array($normalizer);
$serializer = new Serializer($normalizers, $encoders);
$rechercheJson= $serializer->serialize($recherche, 'json');

And this is how I deserialize it :

$encoders = array(new JsonEncoder());
$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(array('parent', 'enfants'));
$normalizer->setCircularReferenceHandler(function ($object) {
    return $object->getCode();
});
$normalizers = array($normalizer);
$serializer = new Serializer($normalizers, $encoders);
$recherche = $serializer->deserialize($recherche_json, Recherche::class, 'json');

I think maybe there is something to do with normalizer, but I can't find anything that helps me in the docs.

Anyone has an idea to help ?

Thanks !

EDIT : After seeing this post : Denormalize nested structure in objects with symfony 2 serializer

I tried this :

$encoders = array(new JsonEncoder());
            $normalizer = new ObjectNormalizer(null, null, null, new SerializationPropertyTypeExtractor());
            $normalizer->setIgnoredAttributes(array('parent', 'enfants'));
            $normalizer->setCircularReferenceHandler(function ($object) {
                return $object->getCode();
            });
            $normalizers = array($normalizer,  new ArrayDenormalizer());
            $serializer = new Serializer($normalizers, $encoders);
            $recherche = $serializer->deserialize($recherche_json, Recherche::class, 'json');

And the SerializationPropertyTypeExtractor:

class SerializationPropertyTypeExtractor implements PropertyTypeExtractorInterface {
    /**
     * {@inheritdoc}
     */
    public function getTypes($class, $property, array $context = array())
    {
        if (!is_a($class, Recherche::class, true)) {
            return null;
        }

        if ('make' !== $property) {
            return null;
        }

        if ('lieu' === $property)
        {
            return [new Type(Type::BUILTIN_TYPE_OBJECT, true, LieuRecherche::class)];
        }
        if ('categorie' === $property)
        {
            return [new Type(Type::BUILTIN_TYPE_OBJECT, true, Categorie::class)];
        }

        return null;
    }
}

And this works well !

like image 820
wyllyjon Avatar asked Aug 23 '26 17:08

wyllyjon


1 Answers

I had a similar issue and tried to solve the problem with a custom PropertyTypeExtractor. Since I have many Entities with nested Objects this felt quite cumbersome also it doesn't work when the nested Object has nested Object again.

I found a better solution using the PhpDocExtractor and the ReflectionExtractor, which extracts the property info for you.

$encoder = [new JsonEncoder()];
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$normalizer = [new ArrayDenormalizer(), new ObjectNormalizer(null, null, null, $extractor)];
$serializer = new Serializer($normalizer, $encoder);
$result = $serializer->deserialize($data,someEntity::class,'json');

This does all the work for me. I hope this will help someone.

like image 130
LocNgu Avatar answered Aug 26 '26 06:08

LocNgu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!