# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
idp_scheme: '%env(IDP_SCHEME)%'
idp_url: '%env(IDP_URL)%'
academy_scheme: '%env(ACADEMY_SCHEME)%'
mdpilogin_domain: '%env(MDPI_LOGIN_DOMAIN)%'
academy_domain: '%env(ACADEMY_DOMAIN)%'
sso_service: '%env(SSO_SERVICE)%'
ffmpeg_binary: '%env(FFMPEG_BINARY_PATH)%'
ffprobe_binary: '%env(FFPROBE_BINARY_PATH)%'
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
GuzzleHttp\Client:
~
App\EventListener\LogoutSuccessListener:
arguments:
$idp_scheme: "%idp_scheme%"
$idp_url: "%idp_url%"
tags:
- name: 'kernel.event_listener'
event: 'Symfony\Component\Security\Http\Event\LogoutEvent'
dispatcher: security.event_dispatcher.main
App\Event\AfterCoursePublishEvent: // 这个这只是一个服务名称,换成 tt 也是可以的
class: App\EventListener\CoursePublishListener
tags:
- {name: 'kernel.event_listener', event: App\Event\AfterCoursePublishEvent, method: 'onCoursePublish'}
#下面这种写法也是可以的(直接定义listerner是,默认会将 App\EventListener\CoursePublishListener 映射为服务名称,这里必须写类名,不能随便起个名字 ,否则会报错),和上面的执行效果相同
# App\EventListener\CoursePublishListener:
# tags:
# - {name: 'kernel.event_listener', event: App\Event\AfterCoursePublishEvent, method: 'onCoursePublish'}
再来看调用,在Repository层,注入Symfony\Component\EventDispatcher\EventDispatcherInterface
$this->eventDispatcher->dispatch(new AfterCoursePublishEvent($data)); //特别注意 这个diapatch 的第二个参数是event_name,这个一定不要传,否则dispatch 不生效,就是这个问题花了我好长时间,巨坑...
还有就是官方文档里关于event_dispatch的介绍,参考:https://symfony.com/doc/current/components/event_dispatcher.html,中有一个ContainerBuilder注册特别坑,根本不知道在哪里使用那几行代码,还有就是
文档里提到的:
Registering service definitions and tagging them with the kernel.event_listener and kernel.event_subscriber tags is not enough to enable the event listeners and event subscribers. You must also register a compiler pass called RegisterListenersPass() in the container builder
这个翻译过过来,就是说光有tags 标注 没有用还要ContainerBuilder注册,实际上就是在service,yaml里 按照上面的两种写法写是可以生效的。
我是参考这个提问作者的问题 改的:https://stackoverflow.com/questions/34923306/dispatcher-doesnt-dispatch-my-event-symfony
关于Subscriber:
①如果是非symfony5框架核心event,需要手动在service,yaml里添加tag标签,比如,Entity调用doctrine.event_subscriber的事件:
App\EventSubscriber\VideoSubscriber:
tags:
- { name: doctrine.event_subscriber }
VideoSubscriber.php部分代码:
...
...
<?php
namespace App\EventSubscriber;
use App\Entity\Video;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
class VideoSubscriber implements EventSubscriber
{
private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function preUpdate(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof Video) {// 这个就是来判断当前事件是来自哪个Entity的,如果不加这个加判断,preUpdate就会对所有Entity生效
$em = $args->getObjectManager();// 这个和$this->entityManager效果相同,但是通过$args获取到的$em 就是当初和$entity绑定的那一个entityManager
$uow = $em->getUnitOfWork();
$changeSet = $uow->getEntityChangeSet($entity);// 获取属性变化,这里 $changeSet['view'],包括两个数据,改变前和改变后的值
if (!isset($changeSet['view']) && !isset($changeSet['voteNum']) && !isset($changeSet['extraView'])) {
$entity->setUpdatedAt(new \DateTime());
}
file_put_contents('./1.txt', $entity->getTitle());
}
}
public function getSubscribedEvents()
{
// TODO: Implement getSubscribedEvents() method.
return [
Events::preUpdate,
];
}
}
...
...
② 如果是symfony5框架核心event,那么可以不用在service,yaml里添加tag标签,像exception这些
