Php 异步事件
我正在尝试为事件设置一个后台处理系统。我正在使用本教程: 我遵循了所有步骤,但我有两个问题:Php 异步事件,php,symfony,events,asynchronous,Php,Symfony,Events,Asynchronous,我正在尝试为事件设置一个后台处理系统。我正在使用本教程: 我遵循了所有步骤,但我有两个问题: 在命令中,我不知道给定给调度程序的事件对象是事件实体还是事件默认类。我认为它应该是默认类,但如果是,如何从订阅服务器中的事件实体获取数据 我的订户似乎没有收到该事件 订户: class QCModifiedSubscriber implements EventSubscriberInterface { public function __construct(EntityManagerInterfac
- 在命令中,我不知道给定给调度程序的事件对象是事件实体还是事件默认类。我认为它应该是默认类,但如果是,如何从订阅服务器中的事件实体获取数据
- 我的订户似乎没有收到该事件
class QCModifiedSubscriber implements EventSubscriberInterface
{
public function __construct(EntityManagerInterface $em, CorrectionReponseService $correctionReponse)
{
$this->em = $em;
$this->correctionReponse = $correctionReponse;
}
public static function getSubscribedEvents()
{
// Liste des évènements écoutés et méthodes à appeler
return array(
'qc.modified' => 'calculStats'
);
}
public function calculStats(Event $event)
{
$data = $event->getData();
$QC = $this->em->getRepository(QC::class)->find($data['qcId']);
$this->correctionReponse->correctionReponsesOfQC($QC);
}
}
services.yml:
services:
PACES\ColleBundle\EventListener\QCModifiedSubscriber:
tags:
- { name: 'kernel.event_subscriber'}
命令:
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getContainer()->get('doctrine')->getManager();
$dispatcher = new EventDispatcher();
while (true) {
$processId = rand(0, 999999999);
# attempts to claim a single event, returns it if successful. may return multiple events.
// note: $processId is some unique id to this process, helps prevent race conditions (see below)
$events = $em->getRepository(Event::class)->claimEvent($processId);
# no events to process, so break out of loop.
if (count($events) === 0) {
break;
}
# iterate over each event to be processed, typically just 1.
foreach ($events as $eventEntity) {
$output->write("Processing id: {$eventEntity->getId()}" . PHP_EOL);
# create the event...
$event = new \Symfony\Component\EventDispatcher\Event($eventEntity);
try {
# dispatch the event!
$dispatcher->dispatch($eventEntity->getName(), $event);
# if we made it here we were successful, mark as processed
$eventEntity->setProcessed(1);
} catch (\Exception $e) {
$eventEntity->setError((string)$e);
}
$em->persist($eventEntity);
$em->flush();
}
}
}
事件实体与教程中的完全相同。因为您在Symfony框架内,正在寻找一个
内核。事件订阅方
,所以您需要使用Symfony的EventDispatcher来调度事件,而不是自己创建一个新实例
确保您的命令扩展:
并更改此行:
$dispatcher = new EventDispatcher();
为此:
$dispatcher = $this->getContainer()->get('event_dispatcher');
为了回答您的另一个问题,提供给调度程序的事件对象是事件类,而不是您的事件实体。你所拥有的也不会在那里工作;如果您查看,类不接受任何构造函数参数
如果不需要向事件侦听器传递任何附加数据,也可以使用默认事件类。在这种情况下,您可以在一个与KerneleEvents类类似的通用StoreEvents类中记录事件及其名称
您应该做的是创建特定于事件实体的事件,如下所示:
namespace AppBundle\Event;
use Symfony\Component\EventDispatcher\Event;
use AppBundle\Entity\Event as EventEntity;
class EntityEvent extends Event
{
const NAME = 'entity.event';
/**
* @var EventEntity
*/
protected $eventEntity;
public function __construct(EventEntity $eventEntity)
{
$this->eventEntity = $eventEntity;
}
public function getEventEntity()
{
return $this->eventEntity;
}
}
现在,您将创建并发送如下事件:
use AppBundle\Event\EntityEvent;
// ...
$event = new EntityEvent($eventEntity);
// ...
$dispatcher->dispatch(EntityEvent::NAME, $event);
然后,当您订阅事件时,您可以通过
$event->getEventEntity()获取事件实体编码>并像平常一样对该事件进行操作。因为您在Symfony框架内,正在寻找一个内核。事件订阅方
,所以您需要使用Symfony的EventDispatcher来调度事件,而不是自己创建一个新实例
确保您的命令扩展:
并更改此行:
$dispatcher = new EventDispatcher();
为此:
$dispatcher = $this->getContainer()->get('event_dispatcher');
为了回答您的另一个问题,提供给调度程序的事件对象是事件类,而不是您的事件实体。你所拥有的也不会在那里工作;如果您查看,类不接受任何构造函数参数
如果不需要向事件侦听器传递任何附加数据,也可以使用默认事件类。在这种情况下,您可以在一个与KerneleEvents类类似的通用StoreEvents类中记录事件及其名称
您应该做的是创建特定于事件实体的事件,如下所示:
namespace AppBundle\Event;
use Symfony\Component\EventDispatcher\Event;
use AppBundle\Entity\Event as EventEntity;
class EntityEvent extends Event
{
const NAME = 'entity.event';
/**
* @var EventEntity
*/
protected $eventEntity;
public function __construct(EventEntity $eventEntity)
{
$this->eventEntity = $eventEntity;
}
public function getEventEntity()
{
return $this->eventEntity;
}
}
现在,您将创建并发送如下事件:
use AppBundle\Event\EntityEvent;
// ...
$event = new EntityEvent($eventEntity);
// ...
$dispatcher->dispatch(EntityEvent::NAME, $event);
然后,当您订阅事件时,您可以通过$event->getEventEntity()获取事件实体编码>并像平时一样处理该事件。非常感谢您的详细回答。它现在工作得很好!很高兴你成功了!文档第一次也让我大吃一惊,我没有意识到从头创建一个新的EventDispatcher
更像是一个独立的工具。非常感谢您的详细回答。它现在工作得很好!很高兴你成功了!文档第一次也让我大吃一惊,我没有意识到从头创建一个新的EventDispatcher
更像是一个独立的工具。