如何在 symfony 5 中验证一些自定义约束
Posted
技术标签:
【中文标题】如何在 symfony 5 中验证一些自定义约束【英文标题】:How to validate some custom constraint in symfony 5 【发布时间】:2021-04-11 14:20:30 【问题描述】:我有 Item 实体类,我必须验证它。我的条件是价格必须小于 1000。如果价格小于 5,库存小于 10,那也是错误的。所以对于第一个条件我使用 LessThan Constraint,但是对于第二个条件我应该怎么做呢?
class Item
/**
* @ORM\Column(type="float")
* @Assert\LessThan(self::ITEM_MAX_PRICE)
*/
private float $price;
/**
* @ORM\Column(type="integer")
*/
private int $stock;
如何验证这两个属性的第二个条件?
【问题讨论】:
symfony.com/doc/current/validation/custom_constraint.html 我已经读过这篇文章,但它是关于一个属性的验证,不是吗? 你也可以在类上放置断言。 换句话说,当你进入类时,你正在与对象(自定义验证器允许你访问)进行交互。 它是域,所以我个人建议这是应该在域代码中实现的逻辑。我添加了一个与我的项目类似的示例。 【参考方案1】:不幸的是,Symfony 没有提供内置约束来验证它们之间的多个属性(顺便说一句,这样做和维护并不容易)。
我建议您查看Callback 约束,它可以灵活地验证您的实体。
但是,如果您的验证逻辑正在增长,我建议您使用custom validator。它是一项服务,因此您可以轻松地注入服务并对其进行测试。
【讨论】:
【参考方案2】:我会使用自定义验证器。这是我的一个项目 (3.4) 中的一个示例。
三个文件:
<?php // src/AppBundle/Validator/Constraint/HasValidDimensions.php
namespace AppBundle\Validator\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class HasValidDimensions extends Constraint
public $invalidWidth = 'Invalid width dimension.';
public $invalidHeight = 'Invalid height dimension.';
public function getTargets()
return self::CLASS_CONSTRAINT;
注意CLASS_CONSTRAINT
的使用。现在,实际的验证器让我可以访问不同的部分(在这种情况下,它是一个命令验证器):
<?php // src/AppBundle/Validator/Constraint/HasValidDimensionsValidator.php
namespace AppBundle\Validator\Constraint;
use AppBundle\Message\Command\PageTemplate\SetPageTemplateDimensions;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* @Annotation
*/
class HasValidDimensionsValidator extends ConstraintValidator
public function validate($setPageTemplateDimensions, Constraint $constraint): void
/* @var SetPageTemplateDimensions $setPageTemplateDimensions */
/* @var HasValidDimensions $constraint */
$pageTemplate = $setPageTemplateDimensions->getPageTemplate();
if ($setPageTemplateDimensions->getWidth() > $pageTemplate->getWidthReal())
$this->context
->buildViolation($constraint->invalidWidth)
->addViolation()
;
if ($setPageTemplateDimensions->getHeight() > $pageTemplate->getHeightReal())
$this->context
->buildViolation($constraint->invalidHeight)
->addViolation()
;
然后在类上使用验证器:
<?php // src/AppBundle/Message/Command/PageTemplate/SetPageTemplateDimensions.php
namespace AppBundle\Message\Command\PageTemplate;
use AppBundle\Validator\Constraint as AppAssert;
/**
* @AppAssert\HasValidDimensions()
*/
class SetPageTemplateDimensions implements TenantOwnedInterface
【讨论】:
【参考方案3】:使用组序列可能很好并且很有用。在这种情况下,首先将检查价格是否小于,并且仅当第一个为真时才会检查另外两个断言 类似的东西:
/**
* @Assert\GroupSequence("Item", "Strict")
*/
class Item
/**
* @ORM\Column(type="float")
* @Assert\LessThan(self::ITEM_MAX_PRICE)
* @Assert\GreaterThan(value=5, groups="Strict")
*/
private float $price;
/**
* @Assert\GreaterThan(value=10, groups="Strict")
* @ORM\Column(type="integer")
*/
private int $stock;
【讨论】:
不幸的是,它一个一个地检查条件,而不是一起检查:( 以这种方式制作带有类目标的自定义验证器可能会很好:)【参考方案4】:所以,我认为你需要看看这个:https://medium.com/@gregurco.vlad/symfony-validation-trick-dependent-validation-eb48bc5e3d81
【讨论】:
以上是关于如何在 symfony 5 中验证一些自定义约束的主要内容,如果未能解决你的问题,请参考以下文章