我有一个控制器,可以将整个请求转发到另一个控制器。第一个控制器是 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");
我碰巧喜欢将控制器定义为服务,但标准方法在大多数情况下都很好用。