Symfony 事件监听器

Symfony EventListener

我创建了一些新事件,例如 app.client_enterapp.client_leave。现在我想注册一个监听器来监听这个事件。如果我在同一个命令中添加一个侦听器,它就会工作。

ClientListener.php

namespace AppBundle\Service;
use AppBundle\Event\ClientEnterEvent;

class ClientListener {

  public function onClientEnter(ClientEnterEvent $event) {
    echo "It could be working";
  }

}

service.yml(更新)

services:
  app.client_listener:
    class: AppBundle\Service\ClientListener
    tags:
      - { name: kernel.event_listener, event: app.client_enter, method: onClientEnter }

ClientCommand.php

namespace AppBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use AppBundle\Event\ClientEnterEvent;

class ClientCommand extends ContainerAwareCommand {
  protected function configure() { ... }
  protected function execute(InputInterface $input, OutputInterface $output) {
    $dispatcher = new EventDispatcher();
    $dispatcher->dispatch('app.client_enter', new ClientEnterEvent("Maxi"));
}

标签name: kernel.event_listener

谢谢大家。我找到了解决方案,在 ContainerAwareCommand 中你必须使用 event_dispatcher.

的服务

ClientCommand.php

namespace AppBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use AppBundle\Event\ClientEnterEvent;

class ClientCommand extends ContainerAwareCommand {
  protected function configure() { ... }
  protected function execute(InputInterface $input, OutputInterface $output) {
    $dispatcher = $this->getContainer->get('event_dispatcher');
    $dispatcher->dispatch('app.client_enter', new ClientEnterEvent("Maxi"));
}

我使用这个服务后,我的事件触发了监听器。

只是提示 hoẃ 让这变得更好。

由于依赖注入在 Symfony 3.3+ 中发生了重大变化,您可以将许多容易出错的代码委托给 Symfony。


简化服务注册

# app/config/services.yml

services:
    _defaults:
        autowire: true

    AppBundle\:
        resouce: '../../src/AppBundle'

它不适用于听众,因为有额外的标签,但它适用于订阅者 - 我建议使用它们来防止任何额外的冗余配置编程。


以简洁的方式获取参数 - 通过构造函数

使用它,您可以开箱即用地在命令中使用构造函数注入。

use Symfony\Component\EventDispatcher\EventDispatcherInterface

class ClientCommand extends Command
{
    /**
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    public function __construct(EventDispatcherInterface $eventDispatcher)
    {
        $this->eventDispatcher = $eventDispatcher;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->eventDispatcher->dispatch(...);
    }  
}

要了解有关 DI 更改的更多信息,请参阅 this post with before/after examples