在Symfony2中使用可扩展实体创建可移植Bundles

时间:2012-03-21 08:44:37

标签: inheritance symfony doctrine-orm

我想创建一些可以在不同项目中重复使用的Symfony2软件包,但是如果需要,也可以轻松扩展实体。

示例可以是可重用的UserBundle,其中包含定义了所有ORM映射的User实体。但是,在我的应用程序中,我可能希望扩展此实体并添加额外的列,关联或覆盖一些父级的映射。

我能找到的最接近的解决方案是Doctrine2的映射超类,但是后来我失去了可重用捆绑包的即插即用性,即使我不这样做,我也总是需要在我的应用程序中扩展映射的超类希望修改映射。

其他记录的继承方案需要修改父级的映射,然后我的UserBundle将不再可移植到项目中。

有没有办法在一个捆绑中定义一个完全正常的实体,并且仍然在另一个捆绑中扩展它?

1 个答案:

答案 0 :(得分:11)

为了将来参考,可以使用target entity resolution解决此问题。

您可以在Symfony docs中找到更多信息。

步骤非常简单:

  1. 在您的包中为User实体

    创建一个界面
    namespace Acme/UserBundle/Model;
    interface UserInterface
    {
        // public functions expected for entity User
    }
    
  2. 让您的基础User实体实现接口

    namespace Acme/UserBundle/Entity;
    /**
     * @ORM\Entity
     */
    class User implements UserInterface
    {
        // implement public functions
    }
    
  3. 像往常一样创建关系,但使用界面

    namespace Acme/InvoiceBundle/Entity;
    /**
     * @ORM\Entity
     */
    class Invoice
    {
        /**
         * @ORM\ManyToOne(targetEntity="Acme\UserBundle\Model\UserInterface")
         */
        protected $user;
    }
    
  4. 通过将以下内容添加到config.yml

    来配置侦听器
    doctrine:
        # ....
        orm:
            # ....
            resolve_target_entities:
                Acme\UserBundle\Model\UserInterface: Acme\UserBundle\Entity\User
    
  5. 如果您想为当前应用程序自定义User实体

    1. User类扩展或实施UserInterface

      namespace Acme/WebBundle/Entity;
      use Acme/UserBundle/Entity/User as BaseUser;
      /**
       * @ORM\Entity
       */
      class User extends BaseUser
      {
          // Add new fields and functions
      }
      
    2. 相应地配置监听器

      doctrine:
          # ....
          orm:
              # ....
              resolve_target_entities:
                  Acme\UserBundle\Model\UserInterface: Acme\WebBundle\Entity\User