首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony2 -如何动态获取Doctrine实体的实体管理器

Symfony2 -如何动态获取Doctrine实体的实体管理器
EN

Stack Overflow用户
提问于 2015-10-20 23:59:17
回答 2查看 1.5K关注 0票数 2

我们正在与许多不同的供应商和客户站点构建一个CMS和网站建设平台,因此有许多不同的内容类型实体,它们是由通用控制器和助手服务编辑的,它们不一定(容易)知道实体管理器对于给定实体是什么。

注意:我们有几个entityManagers来分开访问不同的数据库,例如全局数据库、计费数据库、本地数据库等。

在许多情况下,我们需要检测实体的EntityManager是什么。例如,我们有一个MediaHelper,它动态地将数据库中的媒体与实体上的匹配字段相关联(这不适用于关联,因为媒体必须与任何实体连接,您不能拥有这种动态关联,我们不希望有100个不同的关联)。

媒体在一个由“本地”EntityManager管理的包中。但是该实体可能位于“全局”EntityManager中(您不能假设它位于同一个实体管理器中)。因此,我们需要检测和持久化正确实体管理器的正确实体。

,那么您建议如何动态地检测实体的entityManager?

原始自定义方法

注意:接受的答案是一个更好的解决方案。这只是为了存档目的。

下面是一个简单的解决方案。但我对Symfony和Doctrine还不太了解,不知道这是不是个坏主意?还有人知道吗?如果不是,我不知道为什么这不会是核心,作为一个理论实用程序。

我创建了一个将Doctrine服务注入其中的EntityHelper服务:

代码语言:javascript
复制
gutensite_cms.entity_helper:
    class: Gutensite\CmsBundle\Service\EntityHelper
    arguments:
        - "@doctrine"

然后,在实体助手中有一个简单的函数来获取实体的实体管理器( config.yml已经为实体管理器注册了捆绑包):

代码语言:javascript
复制
/**
 * Automagically find the entityManager for an entity. 
 * @param $entity
 * @return mixed
 */
public function getManagerForEntity($entity) {
    $className = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity));
    foreach (array_keys($this->doctrine->getManagers()) as $name) {
        if(in_array($className, $this->doctrine->getManager($name)->getConfiguration()->getMetadataDriverImpl()->getAllClassNames())) return $em;
    }
}

注意:https://github.com/doctrine/DoctrineBundle/blob/master/Registry.php已经做了一些与这个foreach循环几乎相同的事情,我只是修改了这个想法,返回实体管理器而不是名称空间。

代码语言:javascript
复制
public function getAliasNamespace($alias) {
    foreach (array_keys($this->getManagers()) as $name) {
        try {
            return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias);
        } catch (ORMException $e) {
        }
    }
    throw ORMException::unknownEntityNamespace($alias);
}

更新10/21/15:根据@Cerad的建议更新实体检测代码。

EN

回答 2

Stack Overflow用户

发布于 2015-10-21 00:07:43

根据@qooplmao的建议,理论核心已经有了一种简单的方法。

代码语言:javascript
复制
// 1) get the real class for the entity with the Doctrine Utility.
$class = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity))

// 2) get the manager for that class. 
$entityManager = $this->container->get('doctrine')->getManagerForClass($class);

根据Cerad和Qooplmao的建议,更新10/22/15

票数 1
EN

Stack Overflow用户

发布于 2015-10-21 07:28:26

您能不能给实体管理器一个适合它的上下文的别名呢?您谈论的是环球、计费、本地,例如:

代码语言:javascript
复制
'service_manager' => array(
    'aliases' => array(
        'global_entity_manager' => 'My\Global\EntityManager',
        'billing_entity_manager' => 'My\Billing\EntityManager', 
        'local_entity_manager' => 'My\Local\EntityManager',
    ),
)

还可以将实体管理器映射到实体的命名空间。假设您有一个用于您的全局实体的文件夹,即Global\Entity,那么您可以为这些实体Global\Entity\EntityManager别名实体管理器。该解决方案的优点是可以将多个名称空间映射到同一个实体管理器,因此您的BillingGlobal实体可以轻松地共享相同的实体管理器:

代码语言:javascript
复制
'service_manager' => array(
    'aliases' => array(
        'Global\Entity\EntityManager' => 'My\Global\EntityManager',
        'Billing\Entity\EntityManager' => 'My\Global\EntityManager', // <-same name
        'Local\Entity\EntityManager' => 'My\Local\EntityManager',
    ),
)

这只有在一个名称空间中的实体是由同一个EntityManager实例管理的情况下才能起作用。我很难相信在任何项目中都不会出现这种情况,但否则你可能应该稍微重组一下?:D。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33248792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档