基于其他约束的 Symfony 自定义验证器
Posted
技术标签:
【中文标题】基于其他约束的 Symfony 自定义验证器【英文标题】:Syfmony custom validator based on other Constraints 【发布时间】:2020-10-16 03:31:53 【问题描述】:如何编写自定义验证器?
例如,我有这个工作代码:
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???
提前致谢!
【问题讨论】:
输入你的逻辑并在逻辑被破坏时添加违规。还有 rtfm symfony.com/doc/current/validation/custom_constraint.html 我已经阅读了调频,但我不知道该把逻辑放在哪里?我已经发布了工作逻辑,但不确定如何将其集成到 IdValidator 类中。这就是我寻求帮助的原因。 逻辑在validate
方法中。用$value
做任何你想做的事。如果出现问题 - 向 this->context
添加/构建违规。
【参考方案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)
])
])
];
【讨论】:
【参考方案2】:您没有指定您使用的 Symfony 版本,但如果您有 maker 包,创建验证器的最简单方法是 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();
【讨论】:
我想使用其他约束来验证我的 Id 值。逻辑在问题中,也许我描述得不够好。我已经发布了我现在创建的解决方案的答案,并且似乎运行良好。当然欢迎改进:) 是的,我在你自己的解决方案中看到了,我没有理解正确以上是关于基于其他约束的 Symfony 自定义验证器的主要内容,如果未能解决你的问题,请参考以下文章