Symfony2 / Doctrine - 需要访问数据库的验证约束

时间:2012-01-19 22:57:25

标签: doctrine symfony doctrine-orm

我有一个实体ArticlePattern,它有一个属性pattern(字符串)。我需要访问数据库以检查模式是否正确。所以我想定义一个方法ArticlePattern::isPatternValid()并添加一个约束(使用Doctrine的注释),该约束将在Validator对象验证期间检查isPatternValid是否为真。

从我在这里和那里读到的内容并不是一个好主意,让一个实体依赖于服务容器,这意味着我无法从ArticlePattern :: isPatternValid()内部访问doctrine服务。

那么如何制作需要访问数据库的自定义验证约束呢?你是如何处理这种情况的,我认为看到很多关于从实体类访问服务容器的问题很常见。

修改

好的,谢谢你们,所以答案是Custom Validation Constraint

2 个答案:

答案 0 :(得分:5)

验证器对象可以是:

  • 一个简单的对象,根本没有与框架环境的连接。
  • 一项服务(在dependency injection container的范围内),只要它具有强制性Symfony\Component\Validator\ConstraintValidatorInterface
  • ,它就可以做任何绝对的事情。

那么你需要做什么?

  1. 定义简单约束
  2. 覆盖validatedBy()方法以返回验证程序“name”(return 'my_validator';
  3. 在DIC中定义一个简单的服务:

    <service id="project.validator.my" class="Project\Constraints\MyValidator">
        <!-- service definition here -->
    
        <!-- the service has to be tagged -->
        <tag name="validator.constraint_validator" alias="my_validator" />
    </service>
    

  4. 修改

    您已经询问过多个属性验证。在这种情况下,您可以创建与对象相关的验证器,而不是对象的属性。

    1. 在约束类中定义该约束的目标(属性/类):

      class MyConstraint ... {
          ...
      
          public function targets() {
              return self::CLASS_CONSTRAINT;
          }
      }
      
    2. 注释经过验证的类而不是属性:

      @Assert/MyConstraint(...)
      class MyClass {
          private $firstName;
          private $lastName;
      
          @Assert/Email
          private $email;
      
          ...
      }
      
    3. 验证器本身看起来与验证属性非常相似:

      class MyValidator extends ConstraintValidator {
          public function isValid($value, Constraint $constraint) {
              // $value is an object rather a property
          }
      }
      

答案 1 :(得分:1)

您的约束应覆盖基本validatedBy()方法,并在容器中返回约束验证器服务的ID。

public function validatedBy()
{
    return 'my_pattern_validator';
}