验证实体中的值 - 通过setter或assert验证?

时间:2013-10-11 20:23:20

标签: validation symfony doctrine-orm entity setter

我对验证实体中的值的OOP策略有疑问。假设我有这样的实体:

/*
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="My\PageBundle\Entity\PageRepository")
 */
class File {
    /*
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /*
     * @ORM\Column(name="type", type="string")
     */
    private $type;

    /*
     * @ORM\ManyToOne(targetEntity="File")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    private $parent;
}

现在我想只有实体类型“父”可能是父母。我可以用两种方式做到。

  1. 使用Symfony Callback validation

    if($ this-> getParent()!= null&& $ this-> getParent() - > getType()!='group')     $ context-> addViolationAt('parent','Invalid parent。',array(),null);

  2. 这很明显,但只有在我调用验证器或

    时才有效

    1. 将此逻辑放在setter中,就像它在Symfony book

      中提出的那样
        

      您应该检查生成的实体并根据自己的需要调整getter / setter逻辑

    2.      例如:

      setParent(File $parent) {
          if ($parent->getType() != 'group')
              throw new \Exception('Invalid parent');
          $this->parent = $parent;
      }
      

      哪种方法更好?使用专门为此目的创建的验证约束或getter和setter? 如果使用验证 - 我应该总是使用默认的getter和setter,还是我可以在其中做任何花哨的(和有用的)事情(任何例子)?

1 个答案:

答案 0 :(得分:2)

我会首先使用Symfony回调验证,因为它是用于验证实体的专用构造,因为您的示例更接近用于回调验证的组件的设计理念。

虽然PHP OOP书籍确实鼓励您不仅使用getter和setter来检索属性值,但我总是使用它们来确保字段的默认值和约束(即我有一个 $ id < / strong>属性,类型为 int ,我想确保在设置时将 $ id 的值强制转换为 int 它,即使有人错误地发送了一个字符串/无论如何)。

除此之外,我还认为为setter设置try / catch块是很奇怪的,特别是当我知道我正在发送正确的参数类型时。

更新:刚刚注意到问题的最后部分。我使用我的Symfony getter和setter基本上只是为了检索/存储值。我倾向于为构造函数中的东西设置默认值。多年来我看到了一些代码,其中getter和setter做了一些非常疯狂的事情,它们实际上不属于实体的范围,而是更接近服务或存储库。

我认为实体是允许我将数据库表映射到PHP类的构造 - 它们不需要是智能,特殊或者在该范围之外做任何事情。

我更喜欢保持简单,并使用架构的其余部分来补充可能的操作。它是否能提供一些通用功能并且可以独立隔离?为此提供服务。它与操纵实体,检索某些信息或以特定方式处理它们有关吗?为此建立一个存储库。