Symfony2 在控制器中获取 public 服务

Symfony2 get public services in controller

Sf2 周围流了很多墨水 controller/container。我面临以下情况:

app/console container:debug security
...
> 4
[container] Information for service security.token_storage
Service Id    security.token_interface
Class         Symfony\Component\Security\Core\Authentication\Token ...
...
Public        yes

LoginBundle\DefaultController.php

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
    public function indexAction()
    {
        dump(Controller::get('security.token_storage'));
    ...

显然可以正常工作。

LoginBundle\UserUtilsController

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserUtilsController extends Controller
{
     public function getRoleById()
     {
     dump(Controller::get('security.token_storage'));
     ...

抛出:Error: Call to a member function get() on a non-object

Sf2 Book - Service container中我发现:

In this example, the controller extends Symfony's base Controller, which gives you access to the service container itself. You can then use the get method to locate and retrieve the my_mailer service from the service container.

误区是: - 两个控制器都扩展了基本控制器,后者本身扩展了 ContainerAware,后者实现了设置容器的 ContainerAwareInterface。 - 两个控制器访问相同的 public 服务容器。

那么,为什么第二个控制器不起作用?

我知道这个问题很老,但我不想将控制器作为服务注入,我认为在 services.yml[=17 中重新声明 public 服务是多余和错误的=]

提前致谢。

我自己找到了答案,我想分享给每个处于相同情况的人... UserUtilsController 不起作用,因为它不是以这种方式工作的。如果您了解 Symfony 架构,它会很有趣。

LoginBundle\Controller\UserUtilsController

// For this job we don't need to extends any class..
class UserUtilsController
{
   // but we need a property for injecting the service in it
   private $token;

   // Now let's inject service into our property $token
   public function __construct($token) 
   {
     $this->token = $token;
   } 

   // It's not done but let pretend it is and let's use it
   public function getRoleById()
   {
     ...
     return $this->token->getToken()->getRoles(); 
     ...

services.yml

   #here it's the magic
   services: 
       # this is a new services container 
       user.loggeduser_utils:
            # this is my class (second class)
            class: LoginBundle\Controller\UserUtilsController
            # this is how I feed my _construct argument
            arguments: ["@security.token_storage"]

所以我只是在我的新 class 中注入一个现有服务。

现在,要使用它,我们必须先调用 class:

LoginBundle\Controller\DefaultController.php

class DefaultController extends Controller
{
  public function indexAction()
  {
     // because my class is now a service container we call in this way
     $userRoleId = $this->get('user.loggeduser_utils');
     ...

在理解了 Sf2 DI 模型之后,上面的这个解决方案几乎是微不足道的。