Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 异步事件_Php_Symfony_Events_Asynchronous - Fatal编程技术网

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
更像是一个独立的工具。