短篇小说:我很难在自定义的“供应商”捆绑包中正确使用侦听器。
我正在为Symfony 4.1框架(用于管理用户)编写可重用的捆绑包。我将整个捆绑软件放在了一个新的symfony项目的位置:myproject / lib / AcmeUserBundle / src /
就这样Demo
因为我的捆绑包不在一个平常的地方,所以我这样更改了config / services.yaml(以防万一这是相关事件):
services:
# default configuration for services in *this* file
_defaults:
autowire: true
autoconfigure: true
public: false
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
Acme\UserBundle\:
resource: '../lib/AcmeUserBundle/src/*'
exclude: '../lib/AcmeUserBundle/src/{DependencyInjection,Entity,Migrations,Tests}'
Acme\UserBundle\Controller\:
resource: '../lib/AcmeUserBundle/src/Controller'
tags: ['controller.service_arguments']
然后,我编写了一个登录表单(您不太在乎),并且当用户登录时,我想更新数据库中他的上次日期时间连接信息。因此,我在security.interactive_login
事件的tutorial之后建立了一个侦听器:
<?php
namespace Acme\UserBundle\EventListener;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* LoginListener constructor.
*
* @param EntityManagerInterface $entityManager
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @param InteractiveLoginEvent $event
*/
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
// Get the User entity.
$user = $event->getAuthenticationToken()->getUser();
/** @var \Acme\UserBundle\Entity\User $user */
$user->setLastLoggedAt(new DateTime());
$this->entityManager->persist($user);
$this->entityManager->flush();
}
}
lib / AcmeUserBundle / src / Resources / config / services.yaml 如下:
services:
Acme\UserBundle\EventListener\LoginListener:
tags:
- { name: kernel.event_listener, event: security.interactive_login }
lib / AcmeUserBundle / src / DependencyInjection / AcmeUserExtension.php 如下:
class AcmeUserExtension extends Extension
{
/**
* @param array $configs
* @param ContainerBuilder $container
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.yaml');
}
}
我可以使用以下symfony命令查看我的服务:
php bin/console debug:autowiring
php bin/console debug:container
但是我看不到任何东西:
php bin/console debug:event-dispatcher
当我用用户登录时,不会发生任何错误,当然,数据库中也不会插入任何日期。这就是为什么我认为我的听众未正确注册的原因。
知道为什么吗?
php bin/console debug:container LoginListener
的输出
---------------- ------------------------------------------------
Option Value
---------------- ------------------------------------------------
Service ID Acme\UserBundle\EventListener\LoginListener
Class Acme\UserBundle\EventListener\LoginListener
Tags -
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired yes
Autoconfigured yes
---------------- ------------------------------------------------
我们可以看到 标签 部分为空。这就是为什么我的听众被忽略的原因。 而且...如果我评论我的 config / service.yaml 的一部分,则可以使用:
...
#Acme\UserBundle\:
# resource: '../lib/AcmeUserBundle/src/*'
# exclude: '../lib/AcmeUserBundle/src/{DependencyInjection,Entity,Migrations,Tests}'
...
php bin/console debug:container LoginListener
的新输出
---------------- -----------------------------------------------------------
Option Value
---------------- -----------------------------------------------------------
Service ID Acme\UserBundle\EventListener\LoginListener
Class Acme\UserBundle\EventListener\LoginListener
Tags kernel.event_listener (event: security.interactive_login)
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
---------------- -----------------------------------------------------------
标签 现在是正确的,我的听众可以正常工作