如何在Symfony中的第一个错误时停止对象属性验证?

时间:2018-12-29 12:00:19

标签: php symfony validation

我有以下代码:


    class User
    {
        /**
         * @Assert\Type(type="string")
         * @Assert\NotBlank()
         * @Assert\Email()
         * @Assert\Length(max=255)
         */
        public $email;
    }

此对象是通过API调用填充的。当进行验证并且属性用数组值而不是字符串填充时,NotBlank,Email和Length验证继续起作用,我得到“ UnexpectedTypeException”。

我希望验证系统仅添加关于错误值类型的一个错误并在此处停止。

我已经制作了自定义约束验证器


    class ChainConstraintValidator extends ConstraintValidator
    {
        /**
         * {@inheritdoc}
         */
        public function validate($value, Constraint $constraint)
        {
            if (!$constraint instanceof ChainConstraint) {
                throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\All');
            }

            $context = $this->context;
            $prevCount = $context->getViolations()->count();
            $validator = $context->getValidator()->inContext($context);

            foreach ($constraint->constraints as $constraintStep) {
                $errors = $validator->validate($value, $constraintStep);

                if ($errors->getViolations()->count() > $prevCount) {
                    break;
                }
            }
        }
    }

它有效,我这样使用它:


    @ChainConstraint(
        @Assert\Type(type="string"),
        @Assert\NotBlank(),
        @Assert\Email(),
        @Assert\Length(max=255)
    )
    

我的项目中有很多此类课程。有没有更漂亮,需要更少代码的方法来实现这一目标?

3 个答案:

答案 0 :(得分:2)

Symfony 5.1 开始,可以使用 Sequentially constraint

<块引用>

此约束允许您应用一组应该 逐步验证,允许在验证完成后中断验证 提出了第一次违规。

答案 1 :(得分:0)

您可能会在这些问题中找到一些信息,这些信息似乎与您想要的行为类似:

如这些问题中所述,我认为正确执行此操作的最佳方法是使用group validation,即使在每个断言中执行此操作似乎也很笨拙。

答案 2 :(得分:0)

那呢:

$var = [];

$constraints = [
 new Type(['type'=>'string', 'groups'=> 'first-check']),
 new NotBlank(['groups'=> 'second-check']),
 new Email(['groups'=> 'second-check']),
 new Length(['min'=>2, 'groups'=> 'second-check'])]
    ;

$groups = ['first-check', 'second-check'];
$groupSequence = new GroupSequence($groups);
$error = $validator->validate($var, $constraints, $groupSequence);

if(count($error) > 0) {
    dd($error); // Contains 1 ConstraintViolation (Type) 
 }