symfony 5 - 事件没有被分派

问题描述

我使用事件订阅器来处理提交订单时的一些操作。

问题是我的事件没有被调度,但 symfony 能够找到他,因为他告诉我我的 OrderEvent::ORDER_CREATE 是孤儿。

我预计执行会被 die('Hello you from subscriber'); 停止,但事实并非如此。

控制器

public function commanderPanierAction(Request $request,SelectionWeb $selectionWeb,TableLumineuse $tableLumineuse,EventdispatcherInterface $eventdispatcher)
{
    // DO PREVIoUS STUFF

    $Order = new Order();
    $OrderForm = $this->createForm(OrderForm::class,$Order);
        
    if ($request->isMethod('POST')) {
      $OrderForm->handleRequest($request);

      if ($OrderForm->isSubmitted() && $OrderForm->isValid()) {
          // OrderForm is valid proceed
          $eventdispatcher->dispatch(
              new OrderEvent($Order),OrderEvent::ORDER_CREATE
          );
      }
   } 

订单事件

<?PHP

namespace App\Event;

use App\Entity\Order;
use Symfony\Contracts\Eventdispatcher\Event;

class OrderEvent extends Event
{
    public const ORDER_CREATE = 'order.created';

    protected $order;

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

    public function getorder(): Order
    {
        return $this->order;
    }
}

订单订阅

<?PHP

namespace App\EventSubscriber;

use App\Event\CommandeWebEvent;
use App\Service\SelectionWeb\SelectionWeb;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Eventdispatcher\EventSubscriberInterface;


class OrderSubscriber implements EventSubscriberInterface
{
    private $entityManager;

    private $selectionWeb;

    public function __construct(EntityManagerInterface $entityManager,SelectionWeb $selectionWeb)
    {
        $this->entityManager = $entityManager;
        $this->selectionWeb = $selectionWeb;
    }

    public static function getSubscribedEvents()
    {
        return [
            OrderEvent::ORDER_CREATE => [
                // The higher the number,the earlier the method is called.
                ['processOrder',10],['notifyOrder',-10]
            ]
        ];
    }

    public function processOrder(OrderEvent $event)
    {
        // Todo
        die('Hello you from subscriber');
    }

    public function notifyOrder(OrderEvent $event)
    {
        // Todo
    }
}

编辑

找到的唯一解决方法(感谢@nikserg)是将订阅者注入控制器操作(订阅者具有依赖关系)然后在services.yaml中将我的订阅注册为服务最终在$eventdispatcher->addSubscriber($subscriber);之前使用$eventdispatcher->dispatch(new OrderEvent($Order),OrderEvent::ORDER_CREATE);

对于这么简单的任务来说,所有这些东西似乎都非常复杂

EDIT2

我找到了另一种方法,我可以在不使用 $eventdispatcher->addSubscriber($subscriber); 的情况下执行我的订阅者,并且仅当我将订阅者配置为 $eventdispatcher->dispatch(new OrderEvent($Order)); 中的服务时才使用 services.yaml 但为什么 symfony 会这样做在 services.yaml 中需要这些信息吗?认为 src/ 中的所有内容都可以用作服务..

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.PHP}'

# If I add those It works
App\EventSubscriber\OrderSubscriber:
    autowire: true

EDIT3

我的 OrderSubscriber 已加载到容器中,为什么我应该将其显式设置为正在执行?我不知道发生了什么

PHP bin/console debug:container
---------------------------------------- ---------------------------------------
Service ID                               Class name
---------------------------------------- ----------------------------------------
App\EventSubscriber\OrderSuscriber App\EventSubscriber\OrderSuscriber

编辑 4

如果我明确设置我的 OrderSubscriber,那么它的两个实例到容器中。 为什么 symfony 显式执行一组而不是带有 resource: '../src/*'

的一组

解决方法

Symfony 会将您的订阅者自动装配为服务,如果您需要将其作为行动参数:

public function commanderPanierAction(Request $request,SelectionWeb $selectionWeb,TableLumineuse $tableLumineuse,OrderSubscriber $orderSubscriber)

当然,如果您的订阅者注册正确。

但我建议您不要手动将订阅者创建为对象。关于订阅者的主要好处是,当您触发事件时,您对他们一无所知。此活动可能有数十个订阅者,他们都将继续您的活动。这将使您的代码保持良好状态并降低内聚度。

它在文档中:https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber

,

首先,我要感谢大家的时间,让我道歉,我的问题是由于我写错了 OrderSuscriber 而不是 OrderSubscriber 这就是为什么我的容器中有 2 个服务以及为什么定义服务明确工作。