diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php index 0962dab885..1af03651c3 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php @@ -27,7 +27,7 @@ final class DefaultValueResolver implements ArgumentValueResolverInterface */ public function supports(Request $request, ArgumentMetadata $argument) { - return $argument->hasDefaultValue() || $argument->isNullable(); + return $argument->hasDefaultValue() || ($argument->isNullable() && !$argument->isVariadic()); } /** diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php index 72c294f3a3..32316a8d51 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadata.php @@ -40,7 +40,7 @@ class ArgumentMetadata $this->isVariadic = $isVariadic; $this->hasDefaultValue = $hasDefaultValue; $this->defaultValue = $defaultValue; - $this->isNullable = (bool) $isNullable; + $this->isNullable = $isNullable || null === $type || ($hasDefaultValue && null === $defaultValue); } /** @@ -88,7 +88,7 @@ class ArgumentMetadata } /** - * Returns whether the argument is nullable in PHP 7.1 or higher. + * Returns whether the argument accepts null values. * * @return bool */ diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php index efe5966894..ad6c395ee7 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -58,7 +58,7 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface } foreach ($reflection->getParameters() as $param) { - $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $this->isNullable($param)); + $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $param->allowsNull()); } return $arguments; @@ -88,23 +88,6 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface return $parameter->isDefaultValueAvailable(); } - /** - * Returns if the argument is allowed to be null but is still mandatory. - * - * @param \ReflectionParameter $parameter - * - * @return bool - */ - private function isNullable(\ReflectionParameter $parameter) - { - if ($this->supportsParameterType) { - return null !== ($type = $parameter->getType()) && $type->allowsNull(); - } - - // fallback for supported php 5.x versions - return $this->hasDefaultValue($parameter) && null === $this->getDefaultValue($parameter); - } - /** * Returns a default value if available. * @@ -127,7 +110,16 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface private function getType(\ReflectionParameter $parameter) { if ($this->supportsParameterType) { - return $parameter->hasType() ? (string) $parameter->getType() : null; + if (!$type = $parameter->getType()) { + return; + } + $typeName = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); + if ('array' === $typeName && !$type->isBuiltin()) { + // Special case for HHVM with variadics + return; + } + + return $typeName; } if ($parameter->isArray()) { diff --git a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php index 49931f052c..1ca9a3c798 100644 --- a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php @@ -121,7 +121,7 @@ class ArgumentMetadataFactoryTest extends \PHPUnit_Framework_TestCase new ArgumentMetadata('foo', 'string', false, false, null, true), new ArgumentMetadata('bar', \stdClass::class, false, false, null, true), new ArgumentMetadata('baz', 'string', false, true, 'value', true), - new ArgumentMetadata('mandatory', null, false, false, null), + new ArgumentMetadata('mandatory', null, false, false, null, true), ), $arguments); }