Symfony验证器继承

时间:2018-07-30 16:04:26

标签: php symfony doctrine

我有两个实体类:

class A {

/**
 * @Assert\LessThanOrEqual(3)
 *
 * @var int
 */
protected $attempts;

}

class B extends A {

/**
 * @Assert\LessThanOrEqual(5)
 *
 * @var int
 */
protected $attempts;

}

和1个测试来检查验证是否正常工作:

public function testSetAttemptsCount()
{
    $block = new B();
    $block->setAttempts(6);

    $errors = $this->getService('validator')->validate($block);
    $this->assertHasViolation($errors, 'attempts', LessThanOrEqual::TOO_HIGH_ERROR);

    $block->setAttempts(4);
    $errors = $this->getService('validator')->validate($block);
    $this->assertNotHasViolation($errors, 'attempts', LessThanOrEqual::TOO_HIGH_ERROR);
}

该测试不会通过,因为它可以验证A类的断言值。 有人知道我该如何“重写”字段的验证规则?

1 个答案:

答案 0 :(得分:1)

我现在将结束对解决方案的搜索。显然,有尝试解决此问题,但它导致了某种形式的BC破损,但是我没有找到任何提及(因此我们可以更好地理解它)。毕竟,主要版本允许BC中断,并且我认为3.04.0都是解决此问题的不错的选择,但在某种程度上却使思想有所下滑。

我获得的最佳线索(但无论如何都不是很理想,也不是理想的)是docs中的引言:

  

这意味着您可以向属性添加新约束,但不能覆盖它们   ...   要创建自己的验证,请将约束添加到新的验证组

实际上,定义自己的验证组可能是解决此问题的一种方法,但是如果我们没有对父类的控制(并且通常没有),我们将回到正题。因此,这将涉及在子类中重新定义基类的所有属性。这真的超出了目的。

如果我们将验证规则外部化为YAMLXML,则可以根据上面的推导应用一些不太时髦的解决方案。因此,没有注释。在YAML中,看起来像这样:

App\Data\Foo:
    properties:
        attempts:
            - LessThanOrEqual: 2
        another:
            - LessThanOrEqual: 5

App\Data\Bar:
    properties:
        attempts:
            - LessThanOrEqual: {value: 5, groups: [Overriden]}
        another:
            - LessThanOrEqual: {value: 5, groups: [Overriden]}

在上面的配置示例中,Bar extends Foo和我们可以复制并粘贴现有的验证规则并粘贴自定义group(在我的情况下为Overriden)并使用它。这样,我们可以验证来自父类的约束,这些约束是我们感兴趣的约束,并且包括子类的约束。如果父类使用不同的验证规则格式,则需要付出更多的努力...

我很想看看是否有人能提出更好的方法,因为我认为这确实可以发挥作用。

希望这会有所帮助...