基于其他约束的Syfmony自定义验证器

时间:2020-06-25 15:52:33

标签: php symfony validation

一个人如何编写自定义验证器?

例如,我有以下工作代码:


use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\Validation;



        $input = [
            null,   //fail
            0,      //fail
            1,      //fail
            2,      //fail
            "12",   //ok - string can be (at least 2 chars)
            20,     //ok
            50      //ok
        ];

        $constraint = new Assert\All([
            // the keys correspond to the keys in the input array
            new Assert\NotBlank(),
            new Assert\AtLeastOneOf([
                new Assert\Sequentially([
                    new Assert\Type(['type' => 'int']),
                    new Assert\GreaterThanOrEqual(20)
                ]),
                new Assert\Sequentially([
                    new Assert\Type(['type' => 'string']),
                    new Assert\Length(2)
                ])
            ])
        ]);

        $validator = Validation::createValidator();

        $violations = $validator->validate($input, $constraint);

我想将“支票”打包到一个类中,例如:


        $input = [
            null,   //fail
            0,      //fail
            1,      //fail
            2,      //fail
            "12",   //ok - string can be (at least 2 chars)
            20,     //ok
            50      //ok
        ];

        $constraint = new Assert\All(
            new IdConstraint()
        );

        $validator = Validation::createValidator();

        $violations = $validator->validate($input, $constraint);


IdContrains或IdValidator类应如何显示?这是我到目前为止所得到的:

namespace App\Constraint;

use Symfony\Component\Validator\Constraint;

class IdConstraint extends Constraint
{
    public $message = 'The input "{{ string }}" contains invalid values.';
}
namespace App\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class IdValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        //what to put here???
    }
}

谢谢!

2 个答案:

答案 0 :(得分:1)

我找到了以下解决方案:


namespace App\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class GroupValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        $context = $this->context;

        $validator = $context->getValidator();
        $validations = $validator->validate($value, $constraint->getConstraints());

        if ($validations->count() > 0) {
            $this->context->buildViolation($constraint->message)
                ->setParameter('{{ value }}', (string)$value)
                ->addViolation();
        }
    }
}
<?php

namespace App\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @Annotation
 */
class IdConstraint extends Constraint
{
    public $message = 'The input "{{ value }}" contains invalid values.';

    public function validatedBy()
    {
        return GroupValidator::class;
    }

    public function getConstraints()
    {
        return [
            new Assert\NotBlank(),
            new Assert\AtLeastOneOf([
                new Assert\Sequentially([
                    new Assert\Type(['type' => 'int']),
                    new Assert\GreaterThanOrEqual(20)
                ]),
                new Assert\Sequentially([
                    new Assert\Type(['type' => 'string']),
                    new Assert\Length(2)
                ])
            ])
        ];
    }
}

以及测试代码中的

        $input = [
            null,   //fail
            0,      //fail
            1,      //fail
            2,      //fail
            "12",   //ok - string can be (at leas 2 chars)
            20,     //ok
            50      //ok
        ];

        $constraint = new Assert\All(
            new IdConstraint()
        );

作为替代方案,我看到在Symfony 5.1中可以使用compound,但是我无法在其中设置简单的错误消息。

<?php

namespace App\Constraint;

use Symfony\Component\Validator\Constraints\Compound;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @Annotation
 */
class IdConstraint1 extends Compound
{
    protected function getConstraints(array $options): array
    {
        return [
            new Assert\NotBlank(),
            new Assert\AtLeastOneOf([
                new Assert\Sequentially([
                    new Assert\Type(['type' => 'int']),
                    new Assert\GreaterThanOrEqual(20)
                ]),
                new Assert\Sequentially([
                    new Assert\Type(['type' => 'string']),
                    new Assert\Length(2)
                ])
            ])
        ];
    }
}

答案 1 :(得分:0)

您没有指定正在使用的Symfony版本,但是如果拥有制造商捆绑包,则创建验证器的最简单方法是php bin/console make:validator

作为您的验证代码,您没有提供太多详细信息,但是据我从您的代码中了解,您的验证可能是这样的。

namespace App\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class IdValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        $value = (int) $value;

        if ($value < 10) {
            $this->context->buildViolation($constraint->message)
                ->setParameter('{{ value }}', $value)
                ->addViolation();
        }
    }
}