Symfony 抛出 ServiceCircularReferenceException
Posted
技术标签:
【中文标题】Symfony 抛出 ServiceCircularReferenceException【英文标题】:Symfony throwing ServiceCircularReferenceException 【发布时间】:2018-07-21 06:07:38 【问题描述】:我正在使用 Symfony 2.7,我正在根据以下教程将所有日志写入数据
https://nehalist.io/logging-events-to-database-in-symfony/
我在服务中
monolog.db_handler:
class: AppBundle\Util\MonologDBHandler
arguments: ['@doctrine.orm.entity_manager']
在 monlog db 处理程序中我有以下内容
class MonologDBHandler extends AbstractProcessingHandler
/**
* @var EntityManagerInterface
*/
protected $em;
/**
* MonologDBHandler constructor.
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
parent::__construct();
$this->em = $em;
/**
* Called when writing to our database
* @param array $record
*/
protected function write(array $record)
$logEntry = new Log();
$logEntry->setMessage($record['message']);
$logEntry->setLevel($record['level']);
$logEntry->setLevelName($record['level_name']);
$logEntry->setExtra($record['extra']);
$logEntry->setContext($record['context']);
$this->em->persist($logEntry);
$this->em->flush();
如果我启用开发模式,我会收到以下错误
致命错误:未捕获 Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: 检测到服务的循环参考 “doctrine.orm.default_entity_manager”,路径: “doctrine.orm.default_entity_manager -> 教义.dbal.default_connection -> monolog.logger.doctrine -> monolog.monolog.db_handler"。
我知道这个错误是由于服务原则注入造成的。我该如何解决这个问题。谢谢
【问题讨论】:
这篇文章是为 S3+ 写的。由于事件管理器依赖于它的所有侦听器,因此曾经有很多这样的问题。因此,使侦听器依赖于实体管理器将导致循环依赖。这在 3.x 中被清理了一点。甚至可能是2.8。不确定。我真正能建议的只是查看 2.7 文档以获取示例。 @Cerad.thanks 有什么解决方案可以解决这个问题。我无法升级 symfony,因为它必须改变很多东西 @Cerad.if 我禁用 prod false 然后工作正常。只有当我更改为 true 时才会抛出错误 我必须设置一个 2.7 的环境并搞砸一点。我确定可行的唯一方法是通过全局 $kernel 变量访问实体管理器。不是理想的解决方案,但可能是您最好的选择。 @Cerad.感谢您的努力。我是 symfony 的新手。如果你得到解决方案,请及时发布。谢谢 【参考方案1】:这种方法是一个非常糟糕的主意,应该避免,但您可以通过全局 $kernel 变量访问实体管理器来摆脱循环引用。
class MonologDBHandler extends AbstractProcessingHandler
public function __construct()
parent::__construct();
protected function write(array $record)
global $kernel;
$em = $kernel->getContainer()-get('doctrine.orm.entity_manager');
然后从您的服务定义中删除参数部分。
【讨论】:
出现致命错误:允许的内存大小为 536870912 字节已用完 我确实说过这是个坏主意:) 整篇文章似乎有点可疑。 write 方法可能在实体管理器被刷新时被触发,因此当您将日志对象写出时,它会再次刷新并循环。制作一个second entity manager 仅用于日志记录(可能使用第二个数据库),它可能会起作用。事实上,使用第二个实体管理器可能会让您的原始代码工作。以上是关于Symfony 抛出 ServiceCircularReferenceException的主要内容,如果未能解决你的问题,请参考以下文章
Symfony/PhpUnit - 如何测试服务中是不是抛出异常
Symfony 2 acl isFieldGranted 抛出异常