symfony 5 - 事件未被发送
symfony 5 - event not being dispatched
我使用事件订阅者在提交订单时处理一些操作。
问题是我的事件没有被发送,但是 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
中将我的订阅者注册为服务,最后在 [=18] 之前使用 $eventDispatcher->addSubscriber($subscriber);
=]
看起来所有的东西对于这么简单的任务来说真的很复杂
EDIT2
我找到了另一种方法,我可以在不使用 $eventDispatcher->addSubscriber($subscriber);
的情况下执行我的订阅者,并且仅当我将我的订阅者配置为 services.yaml
中的服务时才使用 $eventDispatcher->dispatch(new OrderEvent($Order));
但是为什么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 个服务和为什么明确定义的服务有效。
我使用事件订阅者在提交订单时处理一些操作。
问题是我的事件没有被发送,但是 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
中将我的订阅者注册为服务,最后在 [=18] 之前使用 $eventDispatcher->addSubscriber($subscriber);
=]
看起来所有的东西对于这么简单的任务来说真的很复杂
EDIT2
我找到了另一种方法,我可以在不使用 $eventDispatcher->addSubscriber($subscriber);
的情况下执行我的订阅者,并且仅当我将我的订阅者配置为 services.yaml
中的服务时才使用 $eventDispatcher->dispatch(new OrderEvent($Order));
但是为什么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 个服务和为什么明确定义的服务有效。