我想将Request对象传递给控制器构造函数,如下所示:
public function __construct(Request $request){
$this->startGameSession($request);
}
但是我收到了一个错误:
Catchable Fatal Error: Argument 1 passed to MyController::__construct() must be an instance of Symfony\Component\HttpFoundation\Request, none given...
同样适用于动作,但不适用于__construct。
答案 0 :(得分:4)
要使用request
中的__constructor
实例,您需要将控制器定义为服务,而是注入request_stack
服务(Ref.)。
控制器可以像任何其他类一样定义为服务。
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RequestStack;
class ServiceController extends Controller
{
public function __construct(RequestStack $requestStack)
{
//do something with $requestStack->getCurrentRequest();
}
}
然后你可以将它定义为一个服务如下(因为Symfony 3.3这可能不是必要的,因为自动装配):
# app/config/services.yml
services:
service_controller:
class: AppBundle\Controller\ServiceController
arguments: ['@request_stack']
您还可以在定义路由_controller
值时使用相同的表示法路由到服务。要引用定义为服务的控制器,请使用单个冒号(:)表示法。:
# app/config/routing.yml
index:
path: /index
defaults: { _controller: service_controller:indexAction }
就是这样!
答案 1 :(得分:2)
在Symfony控制器注册为服务的最新版本(> 3.4 - 不确定自何时起)。 https://symfony.com/doc/current/controller/service.html
只需将 RequestStack $ requestStack 作为参数传递给构造函数。
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RequestStack;
class MyController extends Controller
{
public function __construct(RequestStack $requestStack)
{
$request = $requestStack->getCurrentRequest();
//do something with the $request
}
}
答案 2 :(得分:0)
你添加了:
use Symfony\Component\HttpFoundation\Request;
到您的文件顶部?
答案 3 :(得分:0)
当Symfony内核处理请求时,它正在尝试从请求中解析控制器。
namespace Symfony\Component\HttpKernel\Controller\ControllerResolver;
...
public function getController(Request $request)
{
if (!$controller = $request->attributes->get('_controller')) {
if (null !== $this->logger) {
$this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.');
}
return false;
}
if (is_array($controller)) {
return $controller;
}
if (is_object($controller)) {
if (method_exists($controller, '__invoke')) {
return $controller;
}
throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', get_class($controller), $request->getPathInfo()));
}
if (false === strpos($controller, ':')) {
if (method_exists($controller, '__invoke')) {
return $this->instantiateController($controller);
} elseif (function_exists($controller)) {
return $controller;
}
}
$callable = $this->createController($controller);
if (!is_callable($callable)) {
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s', $request->getPathInfo(), $this->getControllerError($callable)));
}
return $callable;
}
控制器可以是:
__invoke()
的对象,如匿名对象)
函数,是\Closure
)的一个实例。class::method
,BundleName:ControllerName:actionName
或service_id:methodName
模式。方法getController()
返回控制器后,将从控制器生成响应并传递参数。
因此,您无法直接访问控制器构造,因为Symfony正在从Request对象创建控制器。