diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 1a7c314b84f48..27224f5b3d2dc 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -372,7 +372,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex $variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $context, $format); } - $params = array_merge($params, $variadicParameters); + $params = array_merge(array_values($params), $variadicParameters); $unsetKeys[] = $key; } } elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) { diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php new file mode 100644 index 0000000000000..7b3819ac9f034 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures; + +class DummyWithWithVariadicParameterConstructor +{ + private $foo; + + private $bar; + + private $baz; + + public function __construct(string $foo, int $bar = 1, Dummy ...$baz) + { + $this->foo = $foo; + $this->bar = $bar; + $this->baz = $baz; + } + + public function getFoo(): string + { + return $this->foo; + } + + public function getBar(): int + { + return $this->bar; + } + + /** @return Dummy[] */ + public function getBaz(): array + { + return $this->baz; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php index 2500327815cf1..ae627d96a0cc1 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php @@ -29,6 +29,7 @@ use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy; use Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy; use Symfony\Component\Serializer\Tests\Fixtures\Dummy; +use Symfony\Component\Serializer\Tests\Fixtures\DummyWithWithVariadicParameterConstructor; use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\NullableOptionalConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy; @@ -247,6 +248,25 @@ public static function getNormalizer() yield [new ObjectNormalizer(null, null, null, $extractor)]; } + public function testVariadicConstructorDenormalization() + { + $data = [ + 'foo' => 'woo', + 'baz' => [ + ['foo' => null, 'bar' => null, 'baz' => null, 'qux' => null], + ['foo' => null, 'bar' => null, 'baz' => null, 'qux' => null], + ], + ]; + + $normalizer = new ObjectNormalizer(); + $normalizer->setSerializer(new Serializer([$normalizer])); + + $expected = new DummyWithWithVariadicParameterConstructor('woo', 1, new Dummy(), new Dummy()); + $actual = $normalizer->denormalize($data, DummyWithWithVariadicParameterConstructor::class); + + $this->assertEquals($expected, $actual); + } + public static function getNormalizerWithCustomNameConverter() { $extractor = new PhpDocExtractor();