我能否在消费者类中覆盖PHP trait属性以使用Doctrine2注释?

6
我正在使用traits实现Symfony应用程序中的一些可标记行为,使用Doctrine2进行持久化,并使用注释来配置。主要的烦恼是,在trait中,我的IDE不知道$this->tags的类型,并且会弹出一堆警告。我非常在意在此处记录我的代码,以便其他开发人员可以轻松地使用。
trait TaggableMethods {
    /** @var \Doctrine\Common\Collections\Collection */
    protected $tags; // <-- Can't seem to define here…
    public function addTag(Tag $tag) {
        $this->tags->add($tag);
    }
    public function removeTag(Tag $tag) {
        $this->tags->removeElement($tag);
    }
    public function getTags() {
        return $this->tags;
    }
}

class TaggableThingA {
    use TaggableMethods;
    /**
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\ManyToMany(targetEntity="Tag")
     * @ORM\JoinTable(name="ThingA__Tag")
     */
    protected $tags; // <--… because PHP complains about this
}

class TaggableThingB {
    use TaggableMethods;
    /**
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\ManyToMany(targetEntity="Tag")
     * @ORM\JoinTable(name="ThingB__Tag")
     */
    protected $tags;
}

据我所知,我的问题在于我无法在trait中定义$tags属性,因为我需要覆盖注释。我可以避免在TaggableMethods中完全定义$tags,但对我来说,这会破坏封装性,或者至少使代码变得更难阅读。我可以使用Yaml或XML配置持久性,但是我所有其他实体都使用注释。因此,我正在寻找一种避免生成运行时通知的方法,Symfony将其转换为ContextErrorException,在开发过程中终止我的脚本。这可能与“我们可以使用特征来映射Doctrine2中的ManyToOne关系吗?”和“特征-与父类的属性冲突”有关。
此外, "PHP 5.4: why can classes override trait methods with a different signature?" 中提到的继承方法的行为与我想要的属性非常接近 - 有人能解释为什么存在属性和方法之间的差异吗?

你可以在traits中定义映射。 - Absalón Valdés
1
感谢您的回复,但问题(也许是我自己制造的)是我有两个不同的连接表,它们的名称并不标准化。 - TheHud
1
你找到解决方案了吗?我也遇到了同样的问题。 - Alsatian
2个回答

0

我不确定这对我的情况有帮助 - 我需要针对$tags属性定义映射,但是当您重命名属性时,我不知道如何使其工作 - trait中的方法仍然必须引用我在实现中需要定义的属性。 :\ - TheHud

0
虽然有些晚了,但这可能对某些人有所帮助。您可以使用关联或属性覆盖(注释@AssociationOverrides@AttributeOverrides),如6.4. Overrides章节所述。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接