Description
Q | A |
---|---|
Bug report? | yes |
Feature request? | no |
BC Break report? | yes |
RFC? | no |
Symfony version | 4.0.6 |
At the moment the AllValidator
makes the following extra check:
if (!is_array($value) && !$value instanceof \Traversable) {
throw new UnexpectedTypeException($value, 'array or Traversable');
}
it causes a problem to validate whether a value is an array containing only integers.
Let's see the problem in action. Let's say we have an object that has a field $ids
that must be a non-empty array of integers. The naive attempt would be to annotate it like this:
/**
* @var int[]
* @Assert\NotBlank()
* @Assert\Type("array")
* @Assert\All({
* @Assert\Type("int"),
* @Assert\NotBlank(),
* })
*/
private $ids;
It works fine, as soon as you pass an array there. But if you pass non-array and non-iterable value, like 42
it fails miserably with the following exception:
Expected argument of type "array or Traversable", "integer" given
Why does the AllValidator
throws at all?
if (null === $value) {
return;
}
here it checks whether a value is set at all - so that you could validate it with NotBlank
if necessary.
So why does it do the type check with exception, while that part of the job should have been done a Type("array")
constraint instead?
What I suggest:
if (!is_array($value) && !$value instanceof \Traversable) {
return;
}
instead. In that case if the value is not an array or traversable - the validation does not run. And if one wants to ensure it's an array - they must do a naive Type("array")
check first.