Symfony 2.8:无法获取服务中的当前用户(FosUserBundle)


Symfony 2.8: Cannot get current user in Service (FosUserBundle)

我正在尝试访问服务内部的用户,以便跟踪最新的活动。然而,它抛出了一个错误:

错误:在非对象上调用成员函数getUser()

但如果var_dumpdie()用户对象,我可以看到信息。

有什么想法吗?

ActivityListener

<?php
namespace AppBundle'EventListener;
use AppBundle'Entity'User;
use Symfony'Component'EventDispatcher'EventSubscriberInterface;
use Symfony'Component'HttpKernel'Event'FilterControllerEvent;
use Symfony'Component'Routing'Generator'UrlGeneratorInterface;
use Symfony'Component'Security'Core'Authentication'Token'Storage'TokenStorage;
use Symfony'Component'Security'Core'Authentication'Token'Storage'TokenStorageInterface;
class ActivityListener
{
    protected $tokenStorage;
    protected $em;
    public function __construct(TokenStorage $tokenStorage, 'Doctrine'ORM'EntityManager $em)
    {
        $this->tokenStorage     =   $tokenStorage;
        $this->em               =   $em;
    }
    public function onCoreController(FilterControllerEvent $event)
    {
        $user = $this->tokenStorage->getToken()->getUser();
        if($user instanceof User)
        {
            $user->setLastActive(new 'DateTime());
            $this->em->persist($user);
            $this->em->flush($user);
        }
    }
}

服务.yml

 app.activityListener:class: AppBundle'EventListener'ActivityListener
     arguments: [ @security.token_storage, @doctrine.orm.entity_manager ]
     tags: - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }

如您所见:

/**
 * Returns the current security token.
 *
 * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available
 */
public function getToken();

getToken()可以返回TokenInterface对象或null(当用户未登录时)。

将您的方法更改为:

public function onCoreController(FilterControllerEvent $event)
{
    if (is_null($token = $this->tokenStorage->getToken())) {
        return;
    }
    $user = $token->getUser();
    if($user instanceof User)
    {
        $user->setLastActive(new 'DateTime());
        $this->em->persist($user);
        $this->em->flush($user);
    }
}

如果您在var_dumpdie()上看到User对象,那么当监听器被调用多次时,情况一定是这样的,并且它没有用户信息。试着在这里重复一些东西来验证我的理论(在返回之前重复)。它可以与子请求和丢失的身份验证数据连接。

正如前面的人所说,代码可能会多次遍历事件侦听器。我会检查请求是否是主请求,如果不是,继续。之后,从令牌加载用户,并检查它是否真的是用户对象,因为它很可能不是,如果不是的话,再次继续。

public function onCoreController(FilterControllerEvent $event)
{
    if (!$event->isMasterRequest() || !$this->tokenStorage->getToken()) {
        return;
    }
    $user = $this->tokenStorage->getToken()->getUser();
    if (!$user instanceof User) {
        return;
    }
    $user->setLastActive(new 'DateTime());
    $this->em->persist($user);
    $this->em->flush($user);
}