在控制器中访问$ this->容器会引发Catchble Fatal Error异常?

时间:2014-10-08 17:36:56

标签: php symfony

我有以下控制器:

namespace Acme\CompanyBundle\Controller;
use Symfony\Component\DependencyInjection\Container;

/**
 * Company controller.
 *
 */
class CompanyController extends Controller
{
    protected $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function getData()
    {
        $userObj = $this->container->get('security.context')->getToken()->getUser();
    }
}

在我的services.yml文件中,我注入了Container类:

parameters:
    acme.controller.company.class:  Acme\ContainerBundle\Controller\CompanyController

services:
    acme.controller.company:
        class:      %acme.controller.company.class%
        arguments:  [@service_container]

加载此控制器时,出现以下错误:

  

捕获致命错误:参数1传递给   Acme \ CompanyBundle \ Controller \ CompanyController :: __ construct()必须是   Symfony \ Component \ DependencyInjection \ Container的实例,无   给定,在C:\ wamp \ www \ symfony \ app \ cache \ dev \ classes.php中调用   2785年定义   C:\瓦帕\ WWW \ symfony的\ SRC \ Acme公司\ CompanyBundle \控制器\ CompanyController.php   线......

正如您所看到的,这是将Container对象简单地注入控制器,但会抛出错误。这有什么问题?

类似问题发布在另一个SO thread here

3 个答案:

答案 0 :(得分:2)

您不需要在控制器中注入容器,只要它们扩展了您的基础Controller类。

只是做:

namespace Acme\CompanyBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

/**
 * Company controller.
 *
 */
class CompanyController extends Controller
{
    public function getData()
    {
        $userObj = $this->get('security.context')->getToken()->getUser();
    }
}

答案 1 :(得分:1)

默认情况下,路线看起来像这样:

cerad_player_wanabe_list:
    pattern:  /player-request/list
    defaults: 
        _controller: CeradPlayerWanabeBundle:Player/PlayerList:list

Symfony \ Component \ HttpKernel \ HttpKernel :: handle($ request)方法从请求对象中提取_controller属性。如果属性中包含两个冒号,则它会将该属性转换为类名,并使用new运算符创建实例。如果实例实现ContainerAwareInterface,则将容器注入控制器实例。未使用您定义的控制器服务。因此,没有参数传递给构造函数的错误。

另一方面,如果_controller只有一个冒号,那么控制器将作为服务从容器中提取。没有检查ContainerAwareInterface。您可以通过服务定义注入依赖项。

这些都记录在:http://symfony.com/doc/current/cookbook/controller/service.html

因此,对于这个特殊问题,您的路线应该是:

cerad_player_wanabe_list:
    pattern:  /player-request/list
    defaults: 
        _controller: acme.controller.company:action

这确实提出了为什么要尝试将控制器定义为服务的问题。默认方法已经完全符合您的要求,因此您无法获得任何收益。

将服务定义为容器的基本原理是您可以准确控制控制器使用的依赖项。使控制器更易于理解和测试。

注入整个容器几乎破坏了将控制器定义为服务的价值。

答案 2 :(得分:1)

从不且永远不会将容器注入某些东西(服务,控制器或其他) 而是尝试注入securityContext或通过symfony控制器的helper方法访问它,如上所述。

令牌它不是一个对象,因为可能是控制器的路径不在防火墙下