diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index c5bd3ffd9720..00bd8a2a52fa 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -354,7 +354,13 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name)); } - $params = array_merge($params, $data[$paramName]); + $variadicParameters = []; + foreach ($data[$paramName] as $parameterData) { + $variadicParameters[] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $context, $format); + } + + $params = array_merge($params, $variadicParameters); + unset($data[$key]); } } elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) { $parameterData = $data[$key]; diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/VariadicConstructorTypedArgsDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/VariadicConstructorTypedArgsDummy.php new file mode 100644 index 000000000000..9c6fd980a152 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/VariadicConstructorTypedArgsDummy.php @@ -0,0 +1,27 @@ + + * + * 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 VariadicConstructorTypedArgsDummy +{ + private $foo; + + public function __construct(Dummy ...$foo) + { + $this->foo = $foo; + } + + public function getFoo() + { + return $this->foo; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php index 890cb2701930..cce383075a6f 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractNormalizerTest.php @@ -8,11 +8,15 @@ use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; +use Symfony\Component\Serializer\Normalizer\PropertyNormalizer; +use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy; +use Symfony\Component\Serializer\Tests\Fixtures\Dummy; use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\ProxyDummy; use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy; use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer; +use Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorTypedArgsDummy; /** * Provides a dummy Normalizer which extends the AbstractNormalizer. @@ -128,4 +132,21 @@ public function testObjectWithNullableConstructorArgument() $this->assertNull($dummy->getFoo()); } + + /** + * @requires PHP 5.6 + */ + public function testObjectWithVariadicConstructorTypedArguments() + { + $normalizer = new PropertyNormalizer(); + $normalizer->setSerializer(new Serializer([$normalizer])); + $data = ['foo' => [['foo' => 'Foo', 'bar' => 'Bar', 'baz' => 'Baz', 'qux' => 'Qux'], ['foo' => 'FOO', 'bar' => 'BAR', 'baz' => 'BAZ', 'qux' => 'QUX']]]; + $dummy = $normalizer->denormalize($data, VariadicConstructorTypedArgsDummy::class); + + $this->assertInstanceOf(VariadicConstructorTypedArgsDummy::class, $dummy); + $this->assertCount(2, $dummy->getFoo()); + foreach ($dummy->getFoo() as $foo) { + $this->assertInstanceOf(Dummy::class, $foo); + } + } }