在提交订单时,我使用事件订阅者来处理一些操作。
问题我的事件没有被分派,但是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
);
}
}
OrderEvent
<?php
namespace AppEvent;
use AppEntityOrder;
use SymfonyContractsEventDispatcherEvent;
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;
}
}
OrderSubscriber
<?php
namespace AppEventSubscriber;
use AppEventCommandeWebEvent;
use AppServiceSelectionWebSelectionWeb;
use DoctrineORMEntityManagerInterface;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
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->dispatch(new OrderEvent($Order),OrderEvent::ORDER_CREATE);
之前使用$eventDispatcher->addSubscriber($subscriber);
对于这么简单的任务来说,似乎所有的东西都太复杂了
EDIT2
我发现了另一种方法,我可以在不使用$eventDispatcher->addSubscriber($subscriber);
的情况下执行订阅者,只有在services.yaml
中将订阅者配置为服务时才使用$eventDispatcher->dispatch(new OrderEvent($Order));
,但为什么symfony在服务中需要此信息。yaml吗?原以为src/里的所有东西都可以用作service.
# 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
AppEventSubscriberOrderSubscriber:
autowire: true
EDIT3
我的OrderSubscriber被加载到容器中,所以为什么我应该显式地将其设置为正在执行?我不知道发生了什么
php bin/console debug:container
---------------------------------------- ---------------------------------------
Service ID Class name
---------------------------------------- ----------------------------------------
AppEventSubscriberOrderSuscriber AppEventSubscriberOrderSuscriber
编辑4
如果我显式设置OrderSubscriber
,则在容器中有两个实例。为什么symfony显式地执行一组而不是使用resource: '../src/*'
Symfony将自动将您的订阅者作为服务,如果您需要它作为操作参数:
public function commanderPanierAction(Request $request, SelectionWeb $selectionWeb, TableLumineuse $tableLumineuse, OrderSubscriber $orderSubscriber)
当然,如果你的用户注册正确的话。
但是我建议您不要手动创建订阅者作为对象。关于订阅者的主要好处是您什么都不知道关于他们,当你触发事件。这个事件可能有几十个订阅者,他们都将继续您的事件。这将保持你的代码美观,降低内聚。
在docs: https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber
首先我要感谢大家的时间,让我道歉,我的问题是由于一个错字,我写了OrderSuscriber
而不是OrderSubscriber
,这就是为什么有两个服务到我的容器,为什么定义的服务明确地工作。