如何创建自定义验证约束

编辑本页

如何创建自定义验证约束

您可以通过扩展基约束类来创建自定义约束,约束.作为示例,您将创建一个基本验证器,用于检查字符串是否只包含字母数字字符。

创建约束类

首先,您需要创建一个Constraint类并进行扩展约束

  • 注释
  • 属性
12 3 4 5 6 7 8 9 10 11 12 13 14
/ / src /验证器/ ContainsAlphanumeric.php名称空间应用程序验证器使用ob娱乐下载组件验证器约束/ * * *@Annotation* /ContainsAlphanumeric扩展约束公共字符串消息字符串“{{string}}”包含一个非法字符:它只能包含字母或数字。//如果约束有配置选项,将它们定义为公共属性公共字符串模式“严格的”;}

添加@Annotation# \[属性]如果您想在其他类中使用约束类作为注释/属性,则将其添加到约束类。

5.2

使用PHP属性配置约束的功能是在Symfony 5.2中引入的。ob娱乐下载在此之前,Doctrine Annotations是注释约束的唯一方法。

创建验证器本身

如您所见,约束类是相当小的。实际的验证由另一个“约束验证器”类执行。约束验证器类由约束的类指定validatedBy ()方法,该方法具有如下默认逻辑:

1 2 3 4 5
//在Symfony基本的\Cob娱乐下载omponent\Validator\Constraint类公共函数validatedBy()返回静态::类。“验证”;}

换句话说,如果您创建了一个自定义约束(如。MyConstraint), ob娱乐下载Symfony会自动寻找另一个类,MyConstraintValidator在实际执行验证时。

验证器类只有一个必需的方法validate ()

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/ / src /验证器/ ContainsAlphanumericValidator.php名称空间应用程序验证器使用ob娱乐下载组件验证器约束使用ob娱乐下载组件验证器ConstraintValidator使用ob娱乐下载组件验证器异常UnexpectedTypeException使用ob娱乐下载组件验证器异常UnexpectedValueExceptionContainsAlphanumericValidator扩展ConstraintValidator公共函数验证价值、约束约束无效如果(!约束运算符ContainsAlphanumeric) {UnexpectedTypeException (约束, ContainsAlphanumeric::类);}//自定义约束应该忽略null和空值//其他约束(NotBlank, notull等)来处理如果= = =价值||= = =价值) {返回;}如果(!是_string(价值)) {//如果您的验证器不能处理传递的类型,则抛出此异常,以便将其标记为无效UnexpectedValueException (价值“字符串”);//使用管道分离多个类型//抛出新的UnexpectedValueException($value, 'string|int');//像这样访问你的配置选项:如果“严格的”= = =约束->模式){/ /……如果(!preg_match (' / ^ [a-zA-Z0-9] + $ / '价值匹配)) {//参数必须是字符串或实现__toString()的对象->上下文->buildViolation (约束->消息)->setParameter ('{{string}}'价值->addViolation ();}}}

内部validate (),则不需要返回值。相反,您可以在验证器中添加违例上下文属性和值将被认为是有效的,如果它没有导致违规。的buildViolation ()方法将错误消息作为其参数,并返回ConstraintViolationBuilderInterface.的addViolation ()方法调用最后将违例添加到上下文。

使用新的验证器

您可以使用自定义验证器,例如Symfony本身提供的验证器:ob娱乐下载

  • 注释
  • 属性
  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/ / src /实体/ User.php名称空间应用程序实体使用应用程序验证器作为AcmeAssert使用ob娱乐下载组件验证器约束作为断言用户/ /……/ * * *@Assert\ NotBlank *@AcmeAssert\ ContainsAlphanumeric(模式=“松散”)* /受保护的字符串的名字/ /……

如果约束包含选项,那么它们应该是前面创建的自定义constraint类上的公共属性。这些选项可以像Symfony核心约束上的选项一样配置。ob娱乐下载

带有依赖项的约束验证器

如果你在用默认的服务。yaml的配置,那么您的验证器已经注册为服务和标记用必要的validator.constraint_validator.这意味着你可以注入服务或配置和其他服务一样。

创建一组可重用的约束

如果需要在应用程序中一致地应用一组公共约束,则可以扩展复合约束

5.1

复合约束在Symfony 5.1中引入。ob娱乐下载

类约束验证器

除了验证单个属性外,约束还可以将整个类作为其作用域。

例如,假设你也有一个PaymentReceipt实体,您需要确保接收有效负载的电子邮件与用户的电子邮件匹配。首先,创建一个约束并重写getTargets ()方法:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src /验证器/ ConfirmedPaymentReceipt.php名称空间应用程序验证器使用ob娱乐下载组件验证器约束/ * * *@Annotation* /ConfirmedPaymentReceipt扩展约束公共字符串userDoesNotMatchMessage“用户的电邮地址与收据不符”公共函数getTargets()字符串返回自我::CLASS_CONSTRAINT;}}

现在,约束验证器将获得一个对象作为第一个参数validate ()

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/ / src /验证器/ ConfirmedPaymentReceiptValidator.php名称空间应用程序验证器使用ob娱乐下载组件验证器约束使用ob娱乐下载组件验证器ConstraintValidator使用ob娱乐下载组件验证器异常UnexpectedValueExceptionConfirmedPaymentReceiptValidator扩展ConstraintValidator/ * * *@param付款收据$收据*/公共函数验证收据、约束约束无效如果(!收据运算符PaymentReceipt) {UnexpectedValueException (收据, PaymentReceipt::类);}如果(!约束运算符ConfirmedPaymentReceipt) {UnexpectedValueException (约束, ConfirmedPaymentReceipt::类);}receiptEmail收据->getPayload () (“电子邮件”) ? ?userEmail收据->getUser ()->getEmail ();如果userEmail= = !receiptEmail) {->上下文->buildViolation (约束->userDoesNotMatchMessage)->atPath (“user.email”->addViolation ();}}}

提示

atPath ()方法定义与验证错误关联的属性。使用任何有效的PropertyAccess语法来定义这个属性。

类约束验证器必须应用于类本身:

  • 注释
  • 属性
  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12
/ / src /实体/ PaymentReceipt.php名称空间应用程序实体使用应用程序验证器ConfirmedPaymentReceipt/ * * *@ConfirmedPaymentReceipt* /PaymentReceipt/ /……

测试自定义约束

使用ConstraintValidatorTestCase类来简化为自定义约束编写单元测试:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
/ /测试/验证器/ ContainsAlphanumericValidatorTest.php名称空间应用程序测试验证器使用应用程序验证器ContainsAlphanumeric使用应用程序验证器ContainsAlphanumericValidator使用ob娱乐下载组件验证器测试ConstraintValidatorTestCaseContainsAlphanumericValidatorTest扩展ConstraintValidatorTestCase受保护的函数createValidator()返回ContainsAlphanumericValidator ();}公共函数testNullIsValid()->验证器->validate (ContainsAlphanumeric ());->assertNoViolation ();}/ * * *@dataProviderprovideInvalidConstraints * /公共函数testTrueIsInvalid(ContainsAlphanumeric约束->验证器->validate ('...'约束);->buildViolation (“myMessage”->setParameter ('{{string}}''...'->assertRaised ();}公共函数provideInvalidConstraints()可迭代的收益率ContainsAlphanumeric(信息:“myMessage”));/ /……}}
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
ob娱乐下载Symfony 5.4支持通过私人Packagist