令牌存储中的Symfony twig服务用户有时为空

令牌存储中的Symfony twig服务用户有时为空,symfony,Symfony,我有一个服务,我已经定义为一个全局细枝变量,它利用TokenStorageInterface的自动连接来获取当前登录的用户 有时令牌为null,并在尝试访问null对象时引发异常在null上调用成员函数getUser() 这是一个基本的密码 BonusService.php namespace AppBundle\Service; use Doctrine\Common\Persistence\ObjectManager; use Symfony\Component\Security\Core

我有一个服务,我已经定义为一个全局细枝变量,它利用TokenStorageInterface的自动连接来获取当前登录的用户

有时令牌为null,并在尝试访问null对象时引发异常<代码>在null上调用成员函数getUser()

这是一个基本的密码

BonusService.php

namespace AppBundle\Service;

use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class BonusService {

    private $user;
    private $manager;

    __construct(TokenStorageInterface, $tokenStorage, ObjectManager $manager) {
        $this->user = $tokenStorage->getToken()->getUser();    // Sometimes fails here
        $this->manager = $manager;
    }

    public function hasBonuses() {
        return count($this->manager->getRepository(Bonus::class)->findBy(array('contact' => $user)) > 0;
    }
}
服务.yml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: true

    AppBundle\Service\BonusService:
config.yml

twig:
    ...
    globals:
        bonus_service: '@AppBundle\Service\BonusService'
index.html.twig

...
{% if bonus_service.hasBonuses %}Have Bonuses{% endif %}
...
我一直在谷歌上搜索为什么当twig做它的事情时,令牌存储可能是空的。主要出现的一个问题是确保我的路由在防火墙后面,在本例中,它是防火墙,并且需要经过身份验证的用户

另外值得注意的是,我有一个类似的服务,在控制器中使用相同的构造函数。当
BonusService
没有决定使用空令牌并且页面加载时,另一个服务获取令牌没有问题。当我删除对twig中的服务的调用时,页面100%的时间都在加载,即使是其他服务和它的相同构造函数


任何帮助都将不胜感激

在创建服务时,除了将注入的服务存储为引用之外,构造函数应该避免执行更多的操作

class BonusService {

    private $tokenStorage;
    private $manager;

    public function __construct(TokenStorageInterface $tokenStorage, ObjectManager $manager) {
        $this->tokenStorage = $tokenStorage;
        $this->manager = $manager;
    }

    public function hasBonuses() {
        if (!$this-tokenStorage->getToken() instanceof User) {
             return false;
        }
        return count($this->manager->getRepository(Bonus::class)->findBy(array(
            'contact' => $this-tokenStorage->getToken()->getUser())
        ) > 0;
    }
}
您仍然需要检查令牌是否已设置并且是否是用户的实例(或者您的用户如何被调用)


不应在构造函数中使用任何注入的服务的原因是,在该阶段,容器仍在启动并构建所有服务。因此,您的依赖项可能尚未完全初始化。

当用户未登录时,它将为您提供null@Eakethet在这种情况下,用户已登录。(我通常用
is_null()
子句包围令牌,但为简洁起见,我没有将其包含在代码段中)您应该存储对令牌存储的引用,而不是在构造函数中获取用户。令牌可能仍然为空,但应用程序处于两种不同的状态-当调用构造函数时,容器仍在启动。或者,您可以避免将用户存储在服务中,并执行类似于bonus_service.haspownes,{user:app.user}的操作。请永远不要更改您在此处发布的代码(变量/密码/etc隐藏除外)。删除
是空的
会改变一切。