Symfony 2控制器在转发到另一个控制器时丢失容器


Symfony 2 controller loses container when forwarded to another controller

我有一个控制器,可以将整个请求转发到另一个控制器。第一个控制器是 Version1Controller ,并且 $this->controller 不为空,使我可以访问服务。它将请求转发到服务中定义为controller.get_user_trials GetUserTrialsController。在第二个控制器中,$this->container为空。为什么symfony在中途失去了它?有什么方法可以传递容器吗?

下面是演示行为的代码

服务.yml

services:
    controller.get_user_trials:
        class: AppBundle'Controller'GetUserTrialsController

版本1控制器.php

<?php
namespace AppBundle'Controller;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
use Symfony'Component'HttpFoundation'Request;
class Version1Controller extends Controller
{
    public function indexAction(Request $request)
    {
        var_dump("V1Controller " . json_encode(is_null($this->container)));
        return $this->forward("controller.get_user_trials:indexAction");
    }
}

获取用户试用版.php

<?php
namespace AppBundle'Controller;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
use Symfony'Component'HttpFoundation'Request;
class GetUserTrialsController extends Controller
{
    public function indexAction(Request $request)
    {
        var_dump("GetUserTrials " . json_encode(is_null($this->container)));
        return "abc";
    }
}

输出:

string(18) "V1Controller false"
string(13) "GetUserTrials true"
abc

只是为了放大@qooplmao所说的话。 请务必了解,有两种不同的方法可以实例化控制器。

最常见的方法是指定由三部分组成的控制器字符串。 类似于MyBundle:MyController:my。 当遇到这样的字符串时,路由系统会确定控制器类,实例化一个新对象,然后调用 setContainer 来注入容器。

但是,可以使用仅包含两部分的字符串将控制器定义为服务。 执行此操作时,路由系统只需从容器中拉取对象,而无需进行其他处理。 您的控制器完全有可能根本不需要容器,因此注入它毫无意义。

在你的例子中,只需在服务定义中添加对 setContainer 的调用。

services:
  controller.get_user_trials:
    class: AppBundle'Controller'GetUserTrialsController
    calls: [[setContainer, ['@service_container']]]

一切都会好起来的。 或者不要将控制器定义为服务,而只使用:

$this->forward("AppBundle:GetUserTrials:index");

我碰巧喜欢将控制器定义为服务,但标准方法在大多数情况下都很好用。