当用户被识别但进入主页(/
)时,我想将管理员重定向到/admin
,成员重定向到/member
。
控制器看起来像这样:
public function indexAction()
{
if ($this->get('security.context')->isGranted('ROLE_ADMIN'))
{
return new RedirectResponse($this->generateUrl('app_admin_homepage'));
}
else if ($this->get('security.context')->isGranted('ROLE_USER'))
{
return new RedirectResponse($this->generateUrl('app_member_homepage'));
}
return $this->forward('AppHomeBundle:Default:home');
}
如果我的用户登录了,它工作正常,没有问题。但是如果它们不是,我的i18n开关让我得到一个很好的异常:
合并过滤器只适用于数组或散列"AppHomeBundle:默认值:home.html.twig"。
崩溃行:
{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'fr'})) }}
如果我看app.request.get('_route_params')
,它是空的,以及app.request.get('_route')
。
当然,我可以用return $this->homeAction();
代替return $this->forward('AppHomeBundle:Default:home');
来解决我的问题,但我不明白。
内部请求是否覆盖了用户请求?
注意:我使用的是Symfony version 2.2.1 - app/dev/debug
查看Symfony的源代码,当使用forward
时,创建了一个子请求,并且我们不再处于相同的作用域。
/**
* Forwards the request to another controller.
*
* @param string $controller The controller name (a string like BlogBundle:Post:index)
* @param array $path An array of path parameters
* @param array $query An array of query parameters
*
* @return Response A Response instance
*/
public function forward($controller, array $path = array(), array $query = array())
{
$path['_controller'] = $controller;
$subRequest = $this->container->get('request')->duplicate($query, null, $path);
return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}
通过查看Symfony2的作用域文档,他们告诉了为什么请求本身是一个作用域以及如何处理它。但是他们没有告诉为什么在转发时创建子请求。
更多的谷歌把我放在事件监听器上,在那里我了解到子请求可以被处理(细节)。好的,对于子请求类型,但这仍然不能解释为什么用户请求只是被删除。
我的问题变成了:
标题>为什么用户请求在转发时被删除而不复制?
所以,控制器动作是分离的逻辑的一部分。这个函数对彼此一无所知。我的答案是-单动作处理类型的特定请求(例如与特定的uri程序)。来自SF2文档(http://symfony.com/doc/current/book/controller.html#requests-controller-response-lifecycle):
)2路由器从请求中读取信息(例如URI),找到a匹配该信息的路由,并读取_controller参数;
3匹配路由的控制器为执行,控制器内的代码创建并返回a响应对象;
如果你的请求是路径/
,你想要内部动作(让indexAction()
)处理这条路由,执行另一个控制器动作(例如fancyAction()
),你应该准备fancyAction()
。我的意思是使用(例如):
public function fancyAction($name, $color)
{
// ... create and return a Response object
}
:
public function fancyAction()
{
$name = $this->getRequest()->get('name');
$color = $this->getRequest()->get('color');
// ... create and return a Response object
}
示例来自sf2 dosc:
public function indexAction($name)
{
$response = $this->forward('AcmeHelloBundle:Hello:fancy', array(
'name' => $name,
'color' => 'green',
));
// ... further modify the response or return it directly
return $response;
}
请注意further modify the response
如果你真的需要请求对象,你可以尝试:
public function indexAction()
{
// prepare $request for fancyAction
$response = $this->forward('AcmeHelloBundle:Hello:fancy', array('request' => $request));
// ... further modify the response or return it directly
return $response;
}
public function fancyAction(Request $request)
{
// use $request
}