取消给定实体实例上的更多 Doctrine 事件


Cancel further Doctrine events on a given entity instance

为了处理应用程序中一些最后的严重错误,我在两个事件上设置了一个 Doctrine 侦听器:prePersistpreRemove 。发生错误时...

  • 。在持久保存实体时,会将其删除。
  • 。删除实体时,会将其保留回来。

这些操作通过以下方式执行...

$args->getEntityManager()->remove($args->getEntity());
$args->getEntityManager()->persist($args->getEntity());

。分别。但是,如果 prePersistpreRemove 都检测到错误,则会创建一个事件循环:

  1. 实体持久化:触发prePersist
  2. 调用 remove()prePersist 中发生错误。
  3. 实体被删除:触发preRemove
  4. 调用 persist()preRemove 中发生错误。
  5. 回到 1.

为了避免这种情况,我想取消对我的实体的任何进一步事件处理。在这种情况下:当第一次触发prePersist时,它应该以某种方式标记实体,以便它独立于事件链。如果可能,我想避免向我的实体添加字段。

有什么方法可以实现这样的事情吗?或者,也许我应该首先找到另一种方法来取消持久性或删除?

您可以将代码更改为使用事件订阅服务器,而不是事件侦听器,然后可以轻松跟踪任何有错误的对象。

这里有一些伪代码来理解这个想法:

class EventSubscriber implements EventSubscriber
{
    private $hasErrors = [];
    public function getSubscribedEvents()
    {
        return array(
            Events::prePersist,
            Events::preRemove,
        );
    }
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = ...
        if ($error) {
            if (isset($this->hasErrors[$entity->getId()])) {
                return; // don't remove entity
            }
            $this->hasErrors[$entity->getId()] = true;
            $this->getEntityManager()->remove($entity);
        }
    }
    public function preRemove(LifecycleEventArgs $args)
    {
        $entity = ...
        if ($error) {
            if (isset($this->hasErrors[$entity->getId()])) {
                return; // don't persist entity
            }
            $this->hasErrors[$entity->getId()] = true;
            $this->getEntityManager()->persist($entity);
        }
    }
}