学说2:如何解决" targetEntity"和JoinTable" name"动态特质?

时间:2018-04-24 13:38:07

标签: php symfony doctrine-orm doctrine

我想创建实现以下接口的实体。

<?php

namespace App\Entity\Interfaces;
#...

interface FooInterface
{
    /**
     * @param ArrayCollection|FooInterface[] $foo
     */
    public function setFoo($foo);

    /**
     * @return ArrayCollection|FooInterface[]
     */
    public function getFoo();
}

为了简单起见,我想使用trait从中继承属性和方法。所以最后我的实体可能看起来像这些:

<?php

namespace App\Entity\Entity;
#...

class Bar implements FooInterface
{
    use FooTrait;
}

<?php

namespace App\Entity\Entity;
#...

class Baz implements FooInterface
{
    use FooTrait;
}

但我不知道如何动态解决targetEntityname@ORM注释中。

<?php

namespace App\Entity\Traits;
#...

trait FooTrait
{
    /**
     * Many Foo has Many Foo.
     *
     * @ORM\ManyToMany(targetEntity="...")
     * @ORM\JoinTable(
     *     name="..."
     *     joinColumns={@ORM\JoinColumn(name="foo_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="foo_of_id", referencedColumnName="id")}
     * )
     * @ORM\OrderBy({"id" = "ASC"})
     *
     * @var FooInterface[]|ArrayCollection
     */
    protected $foo;

    #...
}

我选择的方法是好的吗?如果是这样我如何解决我的问题?

1 个答案:

答案 0 :(得分:1)

之前我已经完成了这项工作,它非常有趣且有点复杂,但为您的应用提供了大量的灵活性。您要做的是称为动态关系映射。

详细教程为here。我建议你看一下。我将恢复这里的步骤:

  1. 首先,您需要清空要动态映射的关系的ORM注释字段。你不能用注释来做这件事。

  2. 其次,您需要创建一个事件订阅者/侦听器,侦听onLoadClassMetadata事件。我不记得的确切名称,但在Doctrine的活动课程中是一个常数。

  3. 然后,您需要只监听实现所需接口的实体。您将在事件中收到ClassMetadadataInfo的实例,其中包含实体内存的ReflectionClass和一系列有用的方法来检查是否实现了给定的接口,依此类推。< / p>

  4. 根据您的需要,您必须在元数据类中调用mapManyToManymapManyToOnemapOneToMany等。它将一个非常复杂且定义明确的数组作为参数,它包含几乎与注释相同的信息。您可以将其中大部分空置以使用默认值。您需要提供课程信息和字段名称。

  5. 保存,将您的监听器注册为服务,然后享受。

  6.   

    SIDE注意:这不是一项昂贵的操作,因为classMetadata是由doctrine缓存的。