getUser()方法在控制器构造函数中不起作用

时间:2019-08-09 15:12:08

标签: symfony symfony-4.3

我想在Symfony 4.3.2项目的控制器构造中获取用户对象。根据{{​​3}}上的文档,我只需要调用$ this-> getUser()。是的,这适用于动作方法。

但是:试图在构造函数中获取用户无效,因为容器不会在此处初始化,并且getUser方法会引发异常“对成员函数has()的调用为null”:容器为null在这个时间点。

这有效:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class TestController extends AbstractController
{
    public function indexAction()
    {
        dump($this->getUser());
    }
}

这不是:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class TestController extends AbstractController
{
    public function __contruct()
    {
        dump($this->getUser());
    }

    public function indexAction()
    {
    }
}

当我手动注入容器时,一切都很好:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class TestController extends AbstractController
{
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        dump($this->getUser());
    }

    public function indexAction()
    {
    }
}

顺便说一句,这是AbstractController中的getUser方法:

    protected function getUser()
    {
        if (!$this->container->has('security.token_storage')) {
            throw new \LogicException('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle".');
        }
    ...... 

这是一个错误,是容器没有在构造函数中初始化,还是它是一个功能,当您需要构造函数中的用户时必须手动进行初始化?

编辑:使用https://symfony.com/doc/4.0/security.html#retrieving-the-user-object中所示的方式在操作中确实有效,但在构造函数中无效:

    ....
    private $user;

    public function __construct(UserInterface $user)
    {
        $this->user = $user;
    }

产生以下错误消息:Cannot autowire service "App\Controller\TestController": argument "$user" of method "__construct()" references interface "Symfony\Component\Security\Core\User\UserInterface" but no such service exists. Did you create a class that implements this interface?。这就是我要设置用户对象的地方。

2 个答案:

答案 0 :(得分:1)

从不使用 $security->getUser()$this->getUser() 在构造函数中!

身份验证可能尚未完成。(在“服务”中,存储整个“安全性”对象。:

symfony.com/doc/security.html#a-fetching-the-user-object

...,您可以在任何由AbstractController扩展的Controller中使用$this->getUser()。 (只是不在构造函数中)

答案 1 :(得分:0)

通过调用您提到的ControllerResolver方法对控制器进行实例化之后,setContainer 会设置容器。因此,在调用构造函数时,容器在设计上是不可用的。

您可能有一个用例,但我不明白为什么要这么做,因为在您的控制器方法中,您将必须访问$user属性,并且只需输入{{1 }}。您可以按照示例中所示注入整个容器,也可以仅注入get()服务。

Security

我实际上并没有设置安全服务,因为它将在以后通过容器提供。

如果您要执行此操作以对整个类实施访问控制,则可以使用Security annotations

use Symfony\Component\Security\Core\Security;

class TestController extends AbstractController
{
    private $user;

    public function __construct(Security $security)
    {
        $this->user = $security->getUser();
    }

    public function indexAction()
    {
        $user = $this->user; // Just saved you typing five characters
        // At this point the container is available
    }
}