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

时间:2018-06-18 07:58:23

标签: symfony

我有一个服务,我已将其定义为全局twig变量,它使用自动装配TokenStorageInterface以获取当前登录用户。

有时令牌为空,并在尝试访问空对象时抛出异常。 class ParentView: UIViewController { func prepare(for segue: UIStoryboardSegue, sender: Any?) { // we are presenting the nested controller if segue.identifier == "SegueHastagPickerContainer", let destinationController = segue.destination as? HashtagPicker { destinationController.delegate = self } } } extension ParentView: HashTagPickerDelegate { func picked(hashtag: String) { // we just got info from the child controller, do something with it! } }

这是破坏的准系统代码。

BonusService.php

Call to a member function getUser() on null

services.yml

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

config.yml

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

    AppBundle\Service\BonusService:

index.html.twig

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

我一直在谷歌上搜索为什么当树枝正在做它时,令牌存储可能为空的原因。主要出现的一个问题是确保我的路由在防火墙后面,在这种情况下它是并且需要经过身份验证的用户。

另外需要注意的是,我有一个类似的服务,在控制器中使用相同的构造函数。当... {% if bonus_service.hasBonuses %}Have Bonuses{% endif %} ... 没有决定使用空令牌并且页面加载时,其他服务在获取令牌时没有问题。当我在树枝中删除对服务的调用时,页面会100%加载,即使使用其他服务及其相同的构造函数。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

在创建服务时,构造函数应避免执行更多操作,而不是将注入的服务存储为引用。

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

您仍然需要检查令牌是否已设置并且是否是User的实例(或者您的用户被调用)。

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