Symfony throwing ServiceCircularReferenceException

2019-07-26 17:27发布

问题:

I am using Symfony 2.7 and i am writing all logs to data based on below tutorial

https://nehalist.io/logging-events-to-database-in-symfony/

In service i have

 monolog.db_handler:
        class: AppBundle\Util\MonologDBHandler
        arguments: ['@doctrine.orm.entity_manager']

in monlog db handler i have following

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();
    }
}

if i enable dev mode i am getting following error

Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service "doctrine.orm.default_entity_manager", path: "doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> monolog.logger.doctrine -> monolog.monolog.db_handler".

I know this error due to service doctrine injection .how i can sole this issue.Thank you

回答1:

This approach is a really bad idea and should be avoided but you can get rid of the circular reference by accessing the entity manager via the global $kernel variable.

class MonologDBHandler extends AbstractProcessingHandler
{
    public function __construct()
    {
        parent::__construct();
    }
    protected function write(array $record)
    {
        global $kernel;
        $em = $kernel->getContainer()-get('doctrine.orm.entity_manager');

And then remove the arguments section from your service definition.