学说2:如何在特质中动态地解析"targetEntity"和连接表"name"?



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

<?php
namespace AppEntityInterfaces;
#...
interface FooInterface
{
    /**
     * @param ArrayCollection|FooInterface[] $foo
     */
    public function setFoo($foo);
    /**
     * @return ArrayCollection|FooInterface[]
     */
    public function getFoo();
}

使其简单,我想使用特质从中继承属性和方法。因此,最终我的实体看起来与这些相似:

<?php
namespace AppEntityEntity;
#...
class Bar implements FooInterface
{
    use FooTrait;
}

<?php
namespace AppEntityEntity;
#...
class Baz implements FooInterface
{
    use FooTrait;
}

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

<?php
namespace AppEntityTraits;
#...
trait FooTrait
{
    /**
     * Many Foo has Many Foo.
     *
     * @ORMManyToMany(targetEntity="...")
     * @ORMJoinTable(
     *     name="..."
     *     joinColumns={@ORMJoinColumn(name="foo_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORMJoinColumn(name="foo_of_id", referencedColumnName="id")}
     * )
     * @ORMOrderBy({"id" = "ASC"})
     *
     * @var FooInterface[]|ArrayCollection
     */
    protected $foo;
    #...
}

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

我以前做过,这很有趣且有点复杂,但是使您的应用程序具有灵活性。您要做的是被称为动态关系映射。

详细的教程在这里。我建议您看看。我将在这里总结一下步骤:

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

  2. 第二,您需要创建一个事件订阅者/侦听器,聆听loadClassMetadata事件。

  3. 然后,您只需要聆听实现所需接口的实体。您将在事件中收到ClassMetadata的实例,其中包含您实体中的ReflectionClass,以及一堆有用的方法来检查是否实现了给定的接口,等等,例如>

   $metadata = $eventArgs->getMetadata();
   if (!array_key_exists(FooInterface::class,
       $metadata->getReflectionClass()->getInterfaces())) {
            return;
   }
  1. 根据您的需求,您必须调用$metadata->mapManyToMany()->mapManyToOne()->mapOneToMany()等。它以参数为一个复杂且定义良好的数组,其中包含几乎相同的信息,将其提供给注释中。您可以将其中的大多数空白以使用默认值。需要的是您提供targetEntityfieldName(即,在实体类中的属性名称(。

  2. 保存并注册您的听众为服务。您可以使用Doctrine Console命令orm:schema-tool:update --dump-sql调试步骤4的数组配置,该命令打印出它将生成的SQL查询。

旁注:这不是一个昂贵的操作,因为classmetadata被学说缓存。

相关内容

  • 没有找到相关文章

最新更新