【问题标题】:Symfony validator throws exception on invalid CollectionSymfony 验证器在无效集合上抛出异常
【发布时间】:2017-03-01 13:07:30
【问题描述】:

当我尝试使用 Collection 约束来验证标量时,symfony 验证器会抛出异常。我希望它会返回违规行为。

示例代码:

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Collection;

$validator = Validation::createValidator();

$input = 'testtesttest';
$constraints = [
    new Collection([
        'fields' => [
            'one' => new Length(array('min' => 10))
        ]
    ])
];

$violationList = $validator->validate($input, $constraints);

抛出

PHP Fatal error:  Uncaught Symfony\Component\Validator\Exception\UnexpectedTypeException: Expected argument of type "array or Traversable and ArrayAccess", "string" given in vendor/symfony/validator/Constraints/CollectionValidator.php:37

我在这里做错了吗?

对于其他约束类(例如 NotBlank、Type),验证器会在遇到无效内容时将其添加到违规列表中。在 Collection 的情况下让它抛出异常对我来说似乎很奇怪。我是不是做错了什么?

【问题讨论】:

    标签: php validation symfony


    【解决方案1】:

    很抱歉一年后回复,但我遇到了同样的问题。

    我的解决方案是创建一个custom Validation Constraint

    首先,您必须创建一个自定义约束:CustomCollection,其中将包含以下代码(请注意,我的类正在扩展 Collection constraint 而不是默认的 Constraint 类):

    <?php
    
    namespace AppBundle\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraints\Collection;
    
    class CustomCollection extends Collection
    {
        public $message = 'You must provide an array.';
    }
    

    然后你必须实现你的自定义约束的逻辑(在这种情况下验证你的值是一个有效的数组):

    <?php
    
    namespace AppBundle\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraint;
    use Symfony\Component\Validator\Constraints\CollectionValidator;
    
    class CustomCollectionValidator extends CollectionValidator
    {
        public function validate($value, Constraint $constraint)
        {
            if (!\is_array($value)) {
                $this->context->buildViolation($constraint->message)
                    ->addViolation();
                return;
            }
            parent::validate($value, $constraint);
        }
    }
    

    现在,如果我以您的代码为例,您必须将约束从 Collection 更改为 CustomCollection 才能获得违规:

    $input = 'testtesttest';
    $constraints = [
        new CustomCollection([
            'fields' => [
                'one' => new Length(array('min' => 10))
            ]
        ])
    ];
    
    $violationList = $validator->validate($input, $constraints);
    

    【讨论】:

      【解决方案2】:

      您误用了Collection 约束。此约束用于验证集合(例如数组、可遍历对象)。

      您应该将一组约束传递给 validate 方法。

      例如:

      use Symfony\Component\Validator\Validation;
      use Symfony\Component\Validator\Constraints\Length;
      
      $validator = Validation::createValidator();
      
      $input = 'testtesttest';
      $constraints = [
          new Length(array('min' => 10)),
          // ... And other constraints
      ];
      
      $violationList = $validator->validate($input, $constraints);
      

      您可以在此处查看有关验证器的更多信息:https://symfony.com/doc/current/components/validator.html#usage

      【讨论】:

      • 我知道它是用来验证集合的,但是如果它得到一个无效的集合,那么我希望它返回一个违规,而不是抛出一个异常。
      • 例如说我期待这样的数组$array = ['x' =&gt; ['a' =&gt; (int), 'b' =&gt; (string)]]。我需要使用 Collection 约束来确保 $array['x'] 的值是好的,但是如果我得到 ['x' =&gt; 5] 作为输入,那么验证器就会失败
      • 验证是为了验证数据,而不是数据的模式。你总是可以在验证过程中做一些try{...}catch(){}
      • 使用 Collection,您可以为数组/Traversable 中的每个元素设置验证规则,并特别允许/禁止额外或缺失的字段。这不是在验证架构吗?
      • try {...} catch () {} 对于复杂的数组没有用处,因为你无法判断异常是在哪里触发的
      猜你喜欢
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-28
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      相关资源
      最近更新 更多