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

Validation 通过setter或assert验证验证实体中的值?,validation,symfony,doctrine-orm,entity,setter,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")

我对验证实体中的值的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;
}
现在我想知道只有“parent”类型的实体才能是parent。我可以用两种方法来做

  • 使用:

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

  • 这很明显,但只在我调用验证器或

  • 将此逻辑放入setter中,就像在中建议的那样

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

    哪种方法更好?使用专门为此目的创建的验证约束或getter和setter?
    如果使用验证-我是否应该始终使用默认的getter和setter,或者它们是否是我可以在它们内部执行的任何花哨(和有用的)操作(任何示例)?

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

    虽然PHP OOP书籍确实鼓励您不仅使用getter和setter来检索属性值,但我始终使用它们来确保字段上的默认值和约束(也就是说,我有一个$id属性,它的类型是int,我想确保在设置它时将$id的值转换为int,即使有人错误地发送了字符串/任何东西)

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

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

    我认为实体是允许我将数据库表映射到PHP类的结构——它们不需要是智能的、特殊的,也不需要做任何超出该范围的事情

    我更喜欢保持它们的简单,并使用体系结构的其余部分来补充可能的操作。它是否提供了一些通用功能,并且可以独立地进行隔离?为此制作一个服务。它是否与操作实体、检索某些信息或以特定方式处理它们有关?重新制作一个这是肯定的

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