如何在Symfony 4中注册事件监听器?

时间:2018-04-29 21:53:03

标签: symfony symfony4 php-di symfony-eventdispatcher

我正在编写一个Symfony应用程序。意味着:应用程序具有Symfony应用程序的结构,并使用Symfony的 M VC(symfony/http-kernelsymfony/routing等),但它应尽可能与框架无关。所以我没有使用框架的DI,而是使用PHP-DI

现在我添加了symfony/event-dispatcher组件并为所有自定义事件注册了一个监听器。

services.yaml

system.event_handler:
    tags:
        - { name: system.event_handler, event: general.user_message_received, method: handle }
        - { name: system.event_handler, event: xxx.foo, method: handle }
        - { name: system.event_handler, event: yyy.foo, method: handle }
        - { name: system.event_handler, event: zzz.foo, method: handle }

system.event_handler在我的PHP-DI依赖项文件中定义:

...
EventHandlerInterface::class => DI\factory(function(ContainerInterface $container) {
    return new SystemEventHandler(
        $container->get('process_handler.xxx'),
        $container->get('process_handler.yyy'),
        $container->get('process_handler.zzz')
    );
}),
'system.event_handler' => DI\get(EventHandlerInterface::class),
...

现在我收到了一个错误:

  

的RuntimeException

     

“system.event_handler”的定义没有类。如果你打算   要在运行时动态注入此服务,请将其标记为   合成=真。如果这是儿童单独使用的抽象定义   定义,请添加abstract = true,否则指定一个类   摆脱这个错误。

为什么呢?以这种速度使用别名是错误的吗?

好的,我已经用我的事件处理程序的FQCN替换了services.yaml中的别名:

App\Process\SystemEventHandler:
    tags:
        - { name: system.event_handler, event: general.user_message_received, method: handle }
        - { name: system.event_handler, event: xxx.foo, method: handle }
        - { name: system.event_handler, event: yyy.foo, method: handle }
        - { name: system.event_handler, event: zzz.foo, method: handle }

不再有错误。但事件处理程序仍未添加到EventDispatcher

如何在Symfony 4中注册事件监听器(在PHP-DI容器中定义)?

1 个答案:

答案 0 :(得分:0)

PHP-DI被称为Symfony容器的后备。因此,当Symfony中没有定义条目时,它将退出PHP-DI。但是我从来没有尝试在两个容器中定义一个条目,从我的POV(作为PHP-DI的维护者)这不应该起作用。

由于您需要使用Symfony标记,最简单的解决方案是完全在Symfony的配置(而不是PHP-DI)中定义该特定服务。

另一个主要可能是尝试编写Symfony编译器传递来尝试使其工作,但我不知道这是否可行。如果您设法找到一个好的解决方案,请在the GitHub repository中报告,我们可以尝试整合它。