2014-09-01 91 views
1

请考虑以下情况。我有一个拥有一些信息的实体,让我们说一个新闻项目。这个新闻项目包含评论。如何优雅地登录Doctrine2实体

在新闻项目实体中,有calculateStatistics()函数,它返回从新闻项目实体派生的一些统计量及其评论。我曾经在NewsService里有这个计算函数,但后来发现一个服务并不需要,因为我只使用实体内部的信息。

现在,计算功能也做了一些理智的检查。我想在Monolog服务中记录负面结果作为警告。我仍然相信,在这个实体内部有这个计算函数是有效的,因为不需要外部信息/服务。有没有一种优雅的方式来支持实体内部的日志记录?

+1

不要太在意的嘲讽,但登录信息..优雅的方式不是从实体登录;)计算为什么不是,但不记录。请注意,Doctrine允许加载部分实体,以便某些属性可以为NULL,而它们在DB中被赋值,因此实体中的计算甚至不是一个好主意。使用事件自动执行此过程似乎是一种好方法。 – AlterPHP 2014-09-01 21:46:35

+0

我认为这是一个很好的问题。现在,我们实体中的域逻辑会抛出异常,这会在未知的地方崩溃我们的应用程序。我们还可以返回合理的默认值,并让这些实体在这些情况中记录这些事件。 – Rvanlaak 2017-04-19 08:45:53

回答

1

我不认为在Entity中处理日志是一个好主意,因为实体应该尽可能独立,并且没有业务逻辑。我建议通过event listener来完成。考虑这样的配置(我假设你正在使用Doctrine和希望,而一些教义事件进行记录 - 但如果没有,你只需要修改事件的名称,你听):

实体:

class YourEntity implements StatisticInterface 
{ 
    (...) 
    public function calculateStatistics() 
    { 
     (...) 
    } 

} 

config.yml

your_service.statistics_listener: 
     class: Acme\DemoBundle\EventListener\Entity\StatisticsEntityListener 
     arguments: [@logger] 
     tags: 
      - { name: doctrine.event_listener, event: prePersist } 

prePersistmany可能的事件之一,随便挑一个适合大多数

StatisticsEntityListener

class StatisticsEntityListener 
{ 
    public function __construct(Logger $logger) 
    { 
     $this->logger = $logger; 
    } 

    /** 
    * @param LifecycleEventArgs $args 
    */ 
    public function prePersist(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if ($entity instanceof StatisticInterface) { 
      //do whatever you like with your logger and entity 
      $logger->log($entity->calculateStatistics()); 
     } 
    } 
} 

这样你得到的关注很好的分离,你就可以使用您的Monolog