Symfony 2.8:无法获得当前用户服务(FosUserBundle)

时间:2016-04-18 08:36:53

标签: php symfony

我正在尝试访问服务中的用户以跟踪最新活动。但它会引发错误:

  

错误:在非对象

上调用成员函数getUser()

但如果我 var_dump 死() 用户对象,我可以看到这些信息。

有什么想法吗?

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);
        }
    }
}

services.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 }

2 个答案:

答案 0 :(得分:4)

正如你在这里看到的那样:

/**
 * 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()上看到用户对象,那么当监听器被调用的次数超过一次时,它必须是这样的,然后它就没有用户信息。尝试在这里回应一些东西以验证我的理论(在返回之前使用echo)。它可以与子请求和丢失的身份验证数据连接。

答案 1 :(得分:0)

就像上一个人说的那样,代码可能会多次覆盖事件监听器。我会检查请求是否是主请求,如果不是,请继续。之后,从令牌加载用户并检查它是否确实是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);
}