如何在编译Symfony容器之前获取Doctrine实体元数据?

时间:2016-04-12 19:52:38

标签: symfony doctrine-orm

在一个Symfony包中,我定义了一个编译器传递来预处理某些配置。该配置的一部分基于Doctrine实体,因此我需要获取所有应用程序实体的完整元数据信息。

编译器传递很晚执行(PassConfig::TYPE_BEFORE_REMOVING)。我正在使用这样的$container->get('doctrine')来获取实体元数据:

$em = $container->get('doctrine')->getManagerForClass($entityClass);
$entityMetadata = $em->getMetadataFactory()->getMetadataFor($entityClass);

但是,由于在Symfony容器编译期间使用doctrine服务,这会导致某些用户出现随机故障。

2 个答案:

答案 0 :(得分:0)

我建议您更改实体地址。主要是 - 使用接口创建模型并使实体实现它们。

使用resolve_target_entities Doctrine将"转换"他们到特定的班级。

示例代码在此处:https://github.com/Sylius/SyliusResourceBundle/blob/master/DependencyInjection/Compiler/DoctrineTargetEntitiesResolverPass.php

DoctrineBundle注册之前,请确保您的套件已注册

然后 - 在您的整个应用中 - 而不是AppBundle::Entity寻址,使用先前绑定到实体的接口的FQDN。

我已经对编译器和服务进行了一些实验,并且在编译容器进程的基础上,基于跨包服务是一个非常糟糕的主意 ...为什么?它不可靠 - 有时候它会按照你的意愿工作,有时它会像你描述的那样失败。

答案 1 :(得分:0)

谢谢大家的意见和想法。我发布了一个答案来解释我是如何解决这个问题的。

尝试在编译器传递中使用Doctrine服务正在为我们的用户创建越来越多的问题(并且它正在创建其他服务(如Twig)的其他小问题)。所以这对我们的需求来说绝对是一个糟糕的解决方案。

所以最后我决定改变一切。我们不再使用编译器传递来处理配置,而是使用在运行时调用的常规PHP类。

在开发环境中,将为每个请求处理配置。它比以前慢一点,但我们阻止任何缓存问题。在prod环境中,我们使用Doctrine Cache来处理配置一次。此外,我们创建了一个缓存加热器,以便在第一个请求到达应用程序之前创建缓存配置。