信条坚持后的Symfony独白

信条坚持后的Symfony独白,symfony,doctrine-orm,Symfony,Doctrine Orm,我需要用独白记录我所有的用户行为。但只有在行动持续存在的情况下,数据才有条令、插入、更新或删除 我该怎么办?我可以定义一个像afterPersist这样的通用方法来记录每个操作吗 谢谢 编辑: 听众: use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfo

我需要用独白记录我所有的用户行为。但只有在行动持续存在的情况下,数据才有条令、插入、更新或删除

我该怎么办?我可以定义一个像afterPersist这样的通用方法来记录每个操作吗

谢谢

编辑:

听众:

use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\SecurityContextInterface;

class DatabaseLogger
{
    protected $logger;
    protected $security_context;
    protected $request;

    public function __construct(LoggerInterface $logger, ContainerInterface $service_container)
    {
        $this->logger = $logger;
        $this->setSecurityContext($service_container->get('security.context'));
    }

    public function setRequest(RequestStack $request_stack)
    {
        $this->request = $request_stack->getCurrentRequest();
    }

    public function setSecurityContext(SecurityContextInterface $security_context)
    {
        $this->security_context = $security_context;
    }

    public function onFlush(OnFlushEventArgs $args)
    {
        // configure this however you want
    }
}
并在服务中

cc.listener.database_logger:
    class: Cc\HitoBundle\Listener\DatabaseLogger
    tags:
        - { name: doctrine_mongodb.odm.event_listener, event: onFlush }
        - { name: monolog.logger, channel: database_access }
    calls:
        - [ setRequest, [@request_stack] ]
    arguments: [ @logger, @service_container ]
添加安全上下文时出错:

ServiceCircularReferenceException:检测到服务原则\u mongodb.odm.default\u文档\u管理器的循环引用,路径:doctor\u mongodb.odm.default\u document\u manager->doctor\u mongodb.odm.default\u connection->doctor\u mongodb.odm.event\u manager->cc.listener.post\u persist->security.context->security.authentication.manager->security.user.provider.concrete.user\u db


我想你们可以看一看,有一个非常好的条目,讨论了教义的事件


另外,你可以看一下。

我想你可以看一下,有一个非常好的条目,讨论了教义的事件


此外,您还可以查看。

使用以下内容注册侦听器:

构建侦听器:

namespace Acme\MyBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;

class PersistLogger
{
       public $logger;

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

       public function postPersist(LifecycleEventArgs $args)
       {
           // configure this however you want
           $this->logger->addDebug('whatever');
       }
}
在config.yml中注册侦听器

编辑: 如果将用户存储在数据库中(例如,使用FOSUserBundle),则将安全上下文注入条令侦听器会导致循环引用异常。这是因为安全上下文需要注入实体管理器,以便从数据库中获取用户,但由于侦听器的存在,实体管理器依赖于安全上下文

解决方法是注入整个服务容器,这是唯一一次这样做是合理的,并从中获取安全上下文:

namespace Acme\MyBundle\EventListener;

use Psr\Log\LoggerInterface,
    Symfony\Component\DependencyInjection\ContainerInterface,
    Symfony\Component\Security\Core\SecurityContextInterface;

protected $service_container;
protected $logger;

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

public function getSecurityContext() 
{
    return $this->service_container->get('security.context');
}


使用以下内容注册侦听器:

构建侦听器:

namespace Acme\MyBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;

class PersistLogger
{
       public $logger;

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

       public function postPersist(LifecycleEventArgs $args)
       {
           // configure this however you want
           $this->logger->addDebug('whatever');
       }
}
在config.yml中注册侦听器

编辑: 如果将用户存储在数据库中(例如,使用FOSUserBundle),则将安全上下文注入条令侦听器会导致循环引用异常。这是因为安全上下文需要注入实体管理器,以便从数据库中获取用户,但由于侦听器的存在,实体管理器依赖于安全上下文

解决方法是注入整个服务容器,这是唯一一次这样做是合理的,并从中获取安全上下文:

namespace Acme\MyBundle\EventListener;

use Psr\Log\LoggerInterface,
    Symfony\Component\DependencyInjection\ContainerInterface,
    Symfony\Component\Security\Core\SecurityContextInterface;

protected $service_container;
protected $logger;

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

public function getSecurityContext() 
{
    return $this->service_container->get('security.context');
}


@DonCallisto将其更新为点符号,因此它确实是完美的;要获得路由,可以使用注入记录器的相同方式注入请求服务。我想您指的是保存数据的用户,是指当前登录的用户吗?在这种情况下,请插入security context service@security.context,并从中获取用户。@kyrillos是的,这将起作用。但是注入服务是一个好主意,因为它使测试和调试更容易,因为在编译时您将知道是否有问题。如果您注入容器并使用get,那么您只能在运行时知道。您还可以利用类型暗示来确保注入正确的服务。@kyrillos我找不到一个规范的答案来解释为什么不应该注入服务容器,所以我写了一个-。@kyrillos这里有一个我之前回答过的问题:基本上你注入了请求栈,从那里得到了实际的请求。@DonCallisto将它更新为点符号,所以它真的很完美;要获得路由,可以使用注入记录器的相同方式注入请求服务。我想您指的是保存数据的用户,是指当前登录的用户吗?在这种情况下,请插入security context service@security.context,并从中获取用户。@kyrillos是的,这将起作用。但是注入服务是一个好主意,因为它使测试和调试更容易,因为在编译时您将知道是否有问题。如果您注入容器并使用get,那么您只能在运行时知道。您还可以利用类型暗示来确保注入了正确的服务。@kyrillos我找不到关于为什么不应该注入服务容器的标准答案,所以我写了一个-。@kyrillos这里有一个我之前回答过的问题:基本上,您注入了请求\u堆栈,并从那里获得了实际的请求。