Contributed by
Roland Franssen
in #25275.

Symfony 4 程序中所推荐的 事件管理方式 是利用 subscribers 订阅器而不是使用 listeners 监听器,因为只有订阅器才能在使用 服务自动配置 时能够被自动配置。

然而,对于仍希望使用监听的人来说,在 Symfony 4.1 中我们改进了它们(译注:指服务自动配置),以便支持 __invoke() PHP 魔术方法。思考下列服务配置:

1
2
3
# config/services.yaml
App\EventListener\UserListener:
    tags: [{ name: kernel.event_listener, event: kernel.request }]

kernel.event_listener 标签没有定义 method 属性时,Symfony 执行的是名为 on + CamelCased event name(on+驼峰化的事件名称)的方法。本例中,onKernelRequest() 方法会被执行。在 Symfony 4.1 中,如果监听器类没有定义那个方法,Symfony 会去寻找 __invoke() 方法并且执行它,如果找到的话。

实践中,Symfony 4.1 中的 UserListener 类将十分简单:

1
2
3
4
5
6
7
8
9
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 
class UserListener
{
    public function __invoke(GetResponseEvent $event)
    {
        // ...
    }
}

相关地,我们还在背地里对框架中其他部分的 __invoke() 进行了支持,诸如 TemplateController:

1
2
3
4
5
6
7
8
9
10
11
# config/routes.yaml
index:
    path: /
    # before Symfony 4.1 you must add the 'templateAction' method name
    # 在 Symfony 4.1 之前你必须添加 'templateAction' 方法名
    controller: 'Symfony\Bundle\FrameworkBundle\Controller\TemplateController::templateAction'
    # starting from Symfony 4.1, TemplateController includes an __invoke() method
    # 从 Symfony 4.1 起,TemplateController 包括了一个 __invoke() 方法
    controller: 'Symfony\Bundle\FrameworkBundle\Controller\TemplateController'
    defaults:
      template: 'homepage.html.twig'