-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Closed
Closed
Copy link
Labels
Description
Description
Hi symfony!
Currently I'm in a need in preserving array keys when normalize/denormalize variadic parameters.
And hopefully this will be helpful for community.
Next example shows everything I'd like to propose
// serializer/Tests/Normalizer/AbstractNormalizerTest.php
/**
* @dataProvider getNormalizer
*/
public function testVariadicSerializationWithPreservingKeys(AbstractNormalizer $normalizer): void
{
$d1 = new Dummy();
$d1->foo = 'Foo';
$d1->bar = 'Bar';
$d1->baz = 'Baz';
$d1->qux = 'Quz';
$d2 = new Dummy();
$d2->foo = 'FOO';
$d2->bar = 'BAR';
$d2->baz = 'BAZ';
$d2->qux = 'QUZ';
$arr = ["d1" => $d1, "d2" => $d2];
$obj = new VariadicConstructorTypedArgsDummy(...$arr);
$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$normalizer->setSerializer($serializer);
$this->assertEquals(
'{"foo":{"d1":{"foo":"Foo","bar":"Bar","baz":"Baz","qux":"Quz"},"d2":{"foo":"FOO","bar":"BAR","baz":"BAZ","qux":"QUZ"}}}',
$data = $serializer->serialize($obj, 'json')
);
// Currently the result of serialization will be as bellow (without preserving keys)
/*
{
"foo": [
{
"foo": "Foo",
"bar": "Bar",
"baz": "Baz",
"qux": "Quz"
},
{
"foo": "FOO",
"bar": "BAR",
"baz": "BAZ",
"qux": "QUZ"
}
]
}
*/
$dummy = $normalizer->denormalize(json_decode($data, true), VariadicConstructorTypedArgsDummy::class);
$this->assertInstanceOf(VariadicConstructorTypedArgsDummy::class, $dummy);
$this->assertEquals($arr, $dummy->getFoo());
}
Tested with
PHP: 8.1
symfony/serializer:6.2
Example
Seems like there is a simple change needed
// serializer/Normalizer/AbstractNormalizer.php::346
abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface, CacheableSupportsMethodInterface
{
// ...
protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, string $format = null)
{
// ...
// Line: 346
$variadicParameters = [];
// Fix is in respecting $parameterKey while denormalizing parameter
foreach ($data[$paramName] as $parameterKey => $parameterData) {
$variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $attributeContext, $format);
}
// ...
}
// ...
}