【问题标题】:Symfony inject EntityManager in LogoutListenerSymfony 在 LogoutListener 中注入 EntityManager
【发布时间】:2018-02-21 15:45:09
【问题描述】:

使用 Symfony 3.4,我需要在注销前对用户进行持久化,所以我实现了以下监听器:

<?php
namespace c975L\UserBundle\Listeners;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use c975L\UserBundle\Entity\User;

class LogoutListener implements LogoutHandlerInterface
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function logout(Request $request, Response $response, TokenInterface $token)
    {
        $user = $token->getUser();
        if ($user instanceof User) {
            $user->setLatestSignout(new \DateTime());
            $this->em->persist($user);
            $this->em->flush();
        }
    }
}

我已经自动连接到services.yml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: true
    c975L\UserBundle\Listeners\:
        resource: '../../Listeners/*'

但我收到以下编译错误

编译错误:ContainerNxlf3ac\appDevDebugProjectContainer::load(): 无法打开所需的 '/.../var/cache/dev/ContainerNxlf3ac/getLogoutlistener2Service.php' (include_path='.:/usr/share/php')

看起来我必须为服务设置别名,但我无法这样做...

我在使用parent::__construct();时得到了同样的结果

如果 __construct() 被删除但 $this-&gt;em 未定义,则不会出现错误...

[编辑 - 添加防火墙部分]

security.yml

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|fonts|images|js)/
        security: false
    main:
        pattern: ^/
        provider: c975_l_userbundle
        form_login:
            login_path: user_signin
            check_path: user_signin
            default_target_path: user_dashboard
            csrf_token_generator: security.csrf.token_manager
        remember_me:
            secret: '%secret%'
            lifetime: 31536000
            path: /
            secure: true
        anonymous:    true
        logout_on_user_change: true
        logout:
            path: user_signout
            handlers: [c975L\UserBundle\Listeners\Logoutlistener]

【问题讨论】:

  • 我之前没有看到过那种错误信息,而且您指定 Listeners 目录的方式似乎有点奇怪。不是说不行,但这是不寻常的。你是在开发模式下运行吗?您在运行 bin/console 时收到此错误消息?首先验证您是否使用“bin/console debug:container --show-private | grep EntityManager”定义了(应该是)EntotyManagerInterface
  • getLogoutlistener2Service中的2也有点可疑。尽管我想您可能会尝试不同的方法来克服错误,并且可能会迷失方向。
  • 您是否尝试过bin/console debug:autowiring 来检查您的服务是否正确自动连接?还有bin/console debug:container &lt;class name&gt;看服务是否正确存储在容器中?
  • @Cerad 奇怪的 Listeners 目录规范是什么意思?是的,它在开发模式下运行。没有网页上显示的错误。是的,EntityManagerInterface 已定义。对于2,我不知道它为什么在那里,但它在错误消息中
  • @dbrumann for bin/console debug:container LogoutListener 我可以看到相关服务的信息,并且自动连接正确。感谢这些我不知道的命令。

标签: php symfony symfony4 symfony-3.4 symfony3.x


【解决方案1】:

问题出在防火墙部分。在LogoutListener 名称中使用“l”(小写)代替“L”(大写)是一个错误。设置以下工作。

handlers: [c975L\UserBundle\Listeners\LogoutListener]

[编辑] 有个bug,已经被https://github.com/symfony/symfony/pull/26355解决了

【讨论】:

  • 只是想补充一点,从 4.0 开始,您会得到更清晰的服务不存在消息。在早期版本中,容器试图不区分大小写,从而导致诸如此类的问题。
  • 是的,我看到它在 3.3 中被标记为已弃用。我必须完成捆绑包(因为链接到其他人和实时网站),现在我可以移动到 4。再次感谢您的时间和帮助。
猜你喜欢
  • 2014-09-23
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多