我想创建实现以下接口的实体。
<?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;
}
但我不知道如何动态解决targetEntity
和name
在@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;
#...
}
我选择的方法是好的吗?如果是这样我如何解决我的问题?
答案 0 :(得分:1)
之前我已经完成了这项工作,它非常有趣且有点复杂,但为您的应用提供了大量的灵活性。您要做的是称为动态关系映射。
详细教程为here。我建议你看一下。我将恢复这里的步骤:
首先,您需要清空要动态映射的关系的ORM注释字段。你不能用注释来做这件事。
其次,您需要创建一个事件订阅者/侦听器,侦听onLoadClassMetadata
事件。我不记得的确切名称,但在Doctrine的活动课程中是一个常数。
然后,您需要只监听实现所需接口的实体。您将在事件中收到ClassMetadadataInfo
的实例,其中包含实体内存的ReflectionClass
和一系列有用的方法来检查是否实现了给定的接口,依此类推。< / p>
根据您的需要,您必须在元数据类中调用mapManyToMany
,mapManyToOne
,mapOneToMany
等。它将一个非常复杂且定义明确的数组作为参数,它包含几乎与注释相同的信息。您可以将其中大部分空置以使用默认值。您需要提供课程信息和字段名称。
保存,将您的监听器注册为服务,然后享受。
SIDE注意:这不是一项昂贵的操作,因为classMetadata是由doctrine缓存的。