在一个Symfony包中,我定义了一个编译器传递来预处理某些配置。该配置的一部分基于Doctrine实体,因此我需要获取所有应用程序实体的完整元数据信息。
编译器传递很晚执行(PassConfig::TYPE_BEFORE_REMOVING
)。我正在使用这样的$container->get('doctrine')
来获取实体元数据:
$em = $container->get('doctrine')->getManagerForClass($entityClass);
$entityMetadata = $em->getMetadataFactory()->getMetadataFor($entityClass);
但是,由于在Symfony容器编译期间使用doctrine
服务,这会导致某些用户出现随机故障。
答案 0 :(得分:0)
我建议您更改实体地址。主要是 - 使用接口创建模型并使实体实现它们。
使用resolve_target_entities
Doctrine将"转换"他们到特定的班级。
在 DoctrineBundle
注册之前,请确保您的套件已注册。
然后 - 在您的整个应用中 - 而不是AppBundle::Entity
寻址,使用先前绑定到实体的接口的FQDN。
我已经对编译器和服务进行了一些实验,并且在编译容器进程的基础上,基于跨包服务是一个非常糟糕的主意 ...为什么?它不可靠 - 有时候它会按照你的意愿工作,有时它会像你描述的那样失败。
答案 1 :(得分:0)
谢谢大家的意见和想法。我发布了一个答案来解释我是如何解决这个问题的。
尝试在编译器传递中使用Doctrine服务正在为我们的用户创建越来越多的问题(并且它正在创建其他服务(如Twig)的其他小问题)。所以这对我们的需求来说绝对是一个糟糕的解决方案。
所以最后我决定改变一切。我们不再使用编译器传递来处理配置,而是使用在运行时调用的常规PHP类。
在开发环境中,将为每个请求处理配置。它比以前慢一点,但我们阻止任何缓存问题。在prod环境中,我们使用Doctrine Cache来处理配置一次。此外,我们创建了一个缓存加热器,以便在第一个请求到达应用程序之前创建缓存配置。