指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
 # 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这些