getUser() 方法在控制器构造函数中不起作用
getUser() method doesn't work in the controllers constructor
我想在 Symfony 4.3.2 项目的控制器构造函数中获取用户对象。根据 https://symfony.com/doc/4.0/security.html#retrieving-the-user-object 上的文档,我只需要调用 $this->getUser()。是的,这适用于操作方法。
但是:试图在构造函数中获取用户是行不通的,因为这里不会初始化容器,getUser 方法会抛出异常"Call to a member function has() on 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/blog/new-in-symfony-3-2-user-value-resolver-for-controllers 中所示的方式在操作中有效,但在构造函数中无效:
....
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?
。这就是我想设置用户对象的地方。
容器由 ControllerResolver
在 通过调用您提到的 setContainer
方法实例化控制器之后设置。因此,当调用构造函数时,容器在设计上不可用。
你可能有一个用例,但我不明白你为什么要这样做,因为在你的控制器方法中你将不得不访问 $user
属性 并且它只会节省您输入 get()
。您可以注入示例中所示的整个容器,也可以只注入 Security
服务。
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
}
}
我实际上并没有设置安全服务,因为它稍后会通过容器可用。
如果你想这样做以对整个 class 实施访问控制,你可以使用 Security annotations:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
/**
* @IsGranted('ROLE_USER')
*/
class TestController extends AbstractController
{
// Only authenticated user will be able to access this methods
}
永远不要在构造函数中使用$security->getUser()
或$this->getUser()
!!
身份验证可能尚未完成。(在服务中,而是存储整个安全对象。:
symfony.com/doc/security.html#a-fetching-the-user-object
... 并且您可以在使用 AbstractController 扩展的任何控制器中使用 $this->getUser()
。 (只是不在构造函数中)
我想在 Symfony 4.3.2 项目的控制器构造函数中获取用户对象。根据 https://symfony.com/doc/4.0/security.html#retrieving-the-user-object 上的文档,我只需要调用 $this->getUser()。是的,这适用于操作方法。
但是:试图在构造函数中获取用户是行不通的,因为这里不会初始化容器,getUser 方法会抛出异常"Call to a member function has() on 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/blog/new-in-symfony-3-2-user-value-resolver-for-controllers 中所示的方式在操作中有效,但在构造函数中无效:
....
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?
。这就是我想设置用户对象的地方。
容器由 ControllerResolver
在 通过调用您提到的 setContainer
方法实例化控制器之后设置。因此,当调用构造函数时,容器在设计上不可用。
你可能有一个用例,但我不明白你为什么要这样做,因为在你的控制器方法中你将不得不访问 $user
属性 并且它只会节省您输入 get()
。您可以注入示例中所示的整个容器,也可以只注入 Security
服务。
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
}
}
我实际上并没有设置安全服务,因为它稍后会通过容器可用。
如果你想这样做以对整个 class 实施访问控制,你可以使用 Security annotations:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
/**
* @IsGranted('ROLE_USER')
*/
class TestController extends AbstractController
{
// Only authenticated user will be able to access this methods
}
永远不要在构造函数中使用$security->getUser()
或$this->getUser()
!!
身份验证可能尚未完成。(在服务中,而是存储整个安全对象。:
symfony.com/doc/security.html#a-fetching-the-user-object
... 并且您可以在使用 AbstractController 扩展的任何控制器中使用 $this->getUser()
。 (只是不在构造函数中)