Php 多侦听器级联

Php 多侦听器级联,php,symfony,orm,doctrine,Php,Symfony,Orm,Doctrine,我有一个Symfony项目,它使用Doctrine2作为主要ORM。该项目有多个相互关联的实体。我拥有以下实体: Order - order in the shop Product - products in orders Addon - addons for products 对象以以下方式链接: Order |- Product |- Product |- Addon |- Addon 订单和产品实体都有一个“状态”字段。产品的状态与订单的状态相关。产品和订单的状态可以通过几

我有一个Symfony项目,它使用Doctrine2作为主要ORM。该项目有多个相互关联的实体。我拥有以下实体:

Order - order in the shop
Product - products in orders
Addon - addons for products
对象以以下方式链接:

Order
|- Product
|- Product
   |- Addon
   |- Addon
订单和产品实体都有一个“状态”字段。产品的状态与订单的状态相关。产品和订单的状态可以通过几种方式改变;他们需要相互做出反应

我正在考虑使用实体侦听器来侦听实体中的更改。因此,当订单实体的状态发生时,侦听器可以更新产品的状态

检测订单实体中的更改非常有效。但是,当我想改变其产品的地位时,我需要冲淡原则上的变化。当我从OrderListener中刷新产品更改时,Symfony崩溃

TL;DR:检测实体字段中的更改并根据这些更改更新其他实体的最佳方法是什么

提前感谢,

沃特

服务.yml

order_listener:
    class: AppBundle\EntityListener\OrderListener
    arguments: [ '@service_container' ]
    tags:
    - {name: doctrine.event_listener, event: preUpdate}
    - {name: doctrine.event_listener, event: postFlush}
product_listener:
    class: AppBundle\EntityListener\ProductListener
    arguments: [ '@service_container' ]
    tags:
    - {name: doctrine.event_listener, event: preUpdate}
OrderListener

namespace AppBundle\EntityListener;

use AppBundle\Entity\Product;
use AppBundle\Entity\Order;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\DependencyInjection\Container;

class OrderListener {

    /**
     * @var Container
     */
    protected $container;

    /**
     * @var PreUpdateEventArgs[]
     */
    protected $changed = [];

    /**
     * OrderListener constructor.
     *
     * @param Container $container
     */
    public function __construct(Container $container) {

        $this->container = $container;
    }

    public function preUpdate(PreUpdateEventArgs $preUpdateEventArgs){

        if(!$preUpdateEventArgs->getEntity() instanceof Order)
            return;

        $this->changed[] = $preUpdateEventArgs;
    }

    public function postFlush(PostFlushEventArgs $postFlushEventArgs){

        foreach($this->changed as $preUpdateEventArgs){

            /** @var Product $product */
            $em = $this->container->get('doctrine')->getEntityManager();
            foreach($preUpdateEventArgs->getEntity()->getProducts() as $product) {

                $product->setStatus(Product::STATUS_COMPLETED);
                $em->persist($product);
            }

            $em->flush();
        }

        $this->changed = [];
    }
}
ProductListener

namespace AppBundle\EntityListener;

use AppBundle\Entity\Product;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\DependencyInjection\Container;

class ProductListener {

    /**
     * @var Container
     */
    protected $container;

    /**
     * OrderListener constructor.
     *
     * @param Container $container
     */
    public function __construct(Container $container) {

        $this->container = $container;
    }

    public function preUpdate(PreUpdateEventArgs $eventArgs){

        if(!$eventArgs->getEntity() instanceof Product)
            return;

        dump($eventArgs);
    }
}
刷新订单时,Symfony会因以下错误而死亡:

[Symfony\Component\Process\Exception\RuntimeException]  
The process has been signaled with signal "11".   

对其他实体的任何修改都必须在onFlush事件中进行。在预更新中调用persist将产生不可预测的结果。这里有一个很好的例子说明


更多参考可在条令文件中找到

请将您的代码添加到问题中,我们将能够更好地帮助您。您必须仔细阅读条令手册的事件部分。有很多限制和特殊情况。您可以做的一件事是实现“更改通知”,它将在Doctrine的侦听器之外工作。更多代码,但更容易推理。我已经为侦听器添加了代码@奥斯卡佩雷斯