一直在用事件监听,但是之前记录的太简单了,还有很多细节没有理解,现在记录一下
首先是 kernel.event_listener 的 概念:
There is an optional attribute for the kernel.event_listener tag called event which is useful when listener $event argument is not typed. If you configure it, it will change type of $event object. For the kernel.exception event, it is ExceptionEvent. Check out the Symfony events reference to see what type of object each event provides.
With this attribute, Symfony follows this logic to decide which method to call inside the event listener class:
If the kernel.event_listener tag defines the method attribute, that's the name of the method to be called;
If no method attribute is defined, try to call the method whose name is on + "PascalCased event name" (e.g. onKernelException() method for the kernel.exception event);
If that method is not defined either, try to call the __invoke() magic method (which makes event listeners invokable);
If the __invoke() method is not defined either, throw an exception.
翻译过来,使用代码说明:
#service.yaml定义:
App\EventListener\VideoSaveListener:
tags:
# - {name: 'kernel.event_listener', event: App\Event\AfterVideoSaveEvent, method: 'onVideoSave'} #显
- {name: 'kernel.event_listener', event: App\Event\AfterVideoSaveEvent} #隐
VideoSaveListener:
<?php
namespace App\EventListener;
use App\Entity\Video;
use App\Event\AfterVideoSaveEvent;
use App\Service\VideoService;
use Doctrine\ORM\EntityManagerInterface;
class VideoSaveListener
{
private EntityManagerInterface $entityManager;
/**
* 既没有显式也没有隐式定义 method 的时候,会自动调用这个 __invoke 方法
*
* @param AfterVideoSaveEvent $event
* @return void
*/
public function __invoke(AfterVideoSaveEvent $event): void
{
file_put_contents('./3.txt', '3333');
}
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* 显式 定义 method (需要在service 的 tags 里 指定 method 为下面这个方法名)
*/
// public function onVideoSave(AfterVideoSaveEvent $event): void
// {
// file_put_contents('./1.txt', '11111');
// $video = $event->getVideo();
// $length = (new VideoService())->getVideoLength($video->getPlayUrl());
// $video->setLength($length);
//
// $this->entityManager->getRepository(Video::class)->save($video, true);
// }
/**
* 隐式 定义 method (on + 事件名称空间+名称)
*/
// public function onAppEventAfterVideoSaveEvent(AfterVideoSaveEvent $event): void
// {
// file_put_contents('./2.txt', '22222');
// $video = $event->getVideo();
// $length = (new VideoService())->getVideoLength($video->getPlayUrl());
// $video->setLength($length);
//
// $this->entityManager->getRepository(Video::class)->save($video, true);
// }
}
参考:https://symfony.com/doc/current/event_dispatcher.html
