2015-06-19 42 views
1

我正在处理一个EntityRepository类,并且需要将一些数据转储到我的日志文件中。我不能使用dump(),因为这不会构建页面;它只是要返回一些JSON。最终。在Symfony中获取记录器不在控制器中

通常情况下,在控制,我会使用:

$logger = $this->getLogger(); 

但我不是一个控制器。

Thx寻求帮助。

更新:这是用于法医记录。我只是将它用于调试目的。它将在之后被删除。

+1

引用:您不应该将容器传递到存储库,就像您永远不应该让实体处理重逻辑一样。存储库只有一个目的 - 从数据库中检索数据。没有更多(阅读:http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html)。 –

+0

日志记录始终是一项元任务。他们从不为应用程序的服务工作,他们为开发人员服务。在破解之前,你必须知道规则,除非你愿意实现类似AOP的东西,那么你必须稍微打破SRP才能添加日志记录。 –

回答

3

我看了一下。我的第一个预感是“好吧,如果你可以定义EntityRepositories作为服务,那么这将使这很容易,因为你可以然后只是注入记录器”

但是,如何将注入器注入到该教义正在创建的存储库?事实证明,你可以specify your own repository factory

我将假设所有需要的是实现Doctrine\ORM\Repository\RepositoryFactory接口,但你可能想要子类Doctrine\ORM\Repository\DefaultRepositoryFactory

您还需要创建自己的,可以容纳记录器的基础存储库类。让我们从这里开始

的src /的appbundle /教义/ EntityRepository.php

<?php 

namespace AppBundle\Doctrine; 

use Doctrine\ORM\EntityRepository; 
use Psr\Log\LoggerInterface; 

class LoggerAwareEntityRepository extends EntityRepository 
{ 
    protected $logger; 

    public function setLogger(LoggerInterface $logger) 
    { 
     $this->logger = $logger; 
    } 
} 

现在,工厂

的src /的appbundle /教义/ LoggerAwareRepositoryFactory.php

<?php 

namespace AppBundle\Doctrine; 

use Doctrine\ORM\Repository\DefaultRepositoryFactory; 
use Doctrine\ORM\EntityManagerInterface; 
use Psr\Log\LoggerInterface; 
use AppBundle\Doctrine\LoggerAwareEntityRepository; 

class LoggerAwareRepositoryFactory extends DefaultRepositoryFactory 
{ 
    protected $logger; 

    public function __construct(LoggerInterface $logger) 
    { 
     $this->logger = $logger; 
    } 

    protected function createRepository(EntityManagerInterface $entityManager, $entityName) 
    { 
     $repository = parent::createRepository($entityManager, $entityName); 

     if ($repository instanceof LoggerAwareEntityRepository) { 
      $repository->setLogger($this->logger); 
     } 

     return $repository; 
    } 
} 

现在的配置胶水,使其一切工作

应用程序/配置/ services.yml

services: 
    logger_aware_repository_factory: 
     class: AppBundle\Doctrine\LoggerAwareRepositoryFactory 
     arguments: ['@logger'] 

应用程序/配置/ config.yml

doctrine: 
    orm: 
     entity_managers: 
      default: 
       repository_factory: "@logger_aware_repository_factory" 

最后,对于实际执行

的src /的appbundle /Entity/SomeCustomRepository.php

<?php 

namespace AppBundle\Entity; 

use AppBundle\Doctrine\LoggerAwareEntityRepository; 

class SomeCustomRepository extends LoggerAwareEntityRepository 
{ 
    public function findSomethingCustom() 
    { 
     // Log something 
     $this->logger->log('message'); 
    } 
} 

完全披露:这是未经测试的代码 - 可能有错误!

+0

从Doctrine 2.4开始,您也可以直接设置存储库工厂。 $ config-> setRepositoryFactory(new \ AppBundle \ Doctrine \ LoggerAwareRepositoryFactory($ logger)); – Julian

+1

所有这一切只是一个记录器。而在其他框架中,您只需在应用程序中暴露一个。 Symfony已经做出了一些奇怪的选择。 – eggmatters

0

根据您想要记录的内容,最简洁的解决方案是创建一个doctrine或doctrine实体监听器,可能在后期加载。在记录器中注入记录器。 一旦你决定不需要它,只需删除监听器。