我有一个控制器将整个请求转发给另一个控制器。
第一个控制器是Version1Controller
,$this->controller
不为空,这使我可以访问服务。它将请求转发至服务中定义的GetUserTrialsController
controller.get_user_trials
。在第二个控制器中$this->container
为空。 symfony怎么会在中途失去它?有没有办法绕过容器?
以下是演示行为的代码
services.yml
services:
controller.get_user_trials:
class: AppBundle\Controller\GetUserTrialsController
Version1Controller.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");
}
}
GetUserTrials.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
答案 0 :(得分:3)
只是放大了@qooplmao所说的内容。重要的是要了解实例化控制器有两种不同的方法。
最常见的方法是指定一个三部分控制器字符串。像MyBundle:MyController:my。当遇到这样的字符串时,路由系统确定控制器类,实例化一个新对象,然后调用setContainer来注入容器。
但是,您可以使用仅包含两个部分的字符串将控制器定义为服务。执行此操作时,路由系统只需从容器中提取对象而无需其他处理。完全有可能你的控制器根本不需要容器,因此注入它是没有意义的。
在您的情况下,只需在服务定义中添加对setContainer的调用。
services:
controller.get_user_trials:
class: AppBundle\Controller\GetUserTrialsController
calls: [[setContainer, ['@service_container']]]
一切都会好的。或者,不要将控制器定义为服务,只需使用:
$this->forward("AppBundle:GetUserTrials:index");
我碰巧将控制器定义为服务,但标准方法适用于大多数情况。