如何在EventListener中追踪变更并写入数据库?
应用操作监控:ChangeLogListener实现类
我来帮你把这个用于监控应用内实体操作的监听器代码整理好,还补充了一些合理的逻辑示例让它更完整,方便你参考:
class ChangeLogListener implements EventSubscriber { private $tokenStorage; public function __construct(TokenStorage $tokenStorage) { $this->tokenStorage = $tokenStorage; } public function getSubscribedEvents() { return array( 'postPersist', 'postUpdate', 'onDelete', ); } public function postPersist(LifecycleEventArgs $args) { // 避免记录日志自身的操作,防止循环写入 if (!$args->getEntity() instanceof ChangeLog) $this->logChange($args, 'create'); } public function postUpdate(LifecycleEventArgs $args) { if (!$args->getEntity() instanceof ChangeLog) $this->logChange($args, 'update'); } public function onDelete(LifecycleEventArgs $args) { if (!$args->getEntity() instanceof ChangeLog) $this->logChange($args, 'delete'); } /** * 核心日志记录逻辑:生成并持久化操作日志 */ private function logChange(LifecycleEventArgs $args, string $action) { // 获取当前登录用户(如果有) $user = $this->tokenStorage->getToken()?->getUser(); $entity = $args->getEntity(); // 构建ChangeLog实体 $changeLog = new ChangeLog(); $changeLog->setEntityType(get_class($entity)); $changeLog->setEntityId($entity->getId()); $changeLog->setAction($action); $changeLog->setUser($user); $changeLog->setCreatedAt(new \DateTime()); // 持久化日志到数据库 $entityManager = $args->getEntityManager(); $entityManager->persist($changeLog); $entityManager->flush(); } }
几个关键要点说明:
- 这个类实现了Symfony的
EventSubscriber接口,通过getSubscribedEvents方法声明要监听的Doctrine生命周期事件(新增、更新、删除) - 每个事件处理方法里都加了判断:如果操作的是
ChangeLog自身,就跳过记录,避免出现循环写入日志的问题 - 注入
TokenStorage是为了获取当前执行操作的用户,方便把操作人信息记录到日志里 - 把日志记录的核心逻辑抽离到
logChange私有方法里,让代码更整洁,也方便后续统一修改日志规则
内容的提问来源于stack exchange,提问作者Dialkord
相关产品推荐
相关产品推荐

