我想在确定用户后将管理员重定向到/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->forward('AppHomeBundle:Default:home');
替换return $this->homeAction();
来解决我的问题,但我不明白这一点。
内部请求是否覆盖用户请求?
注意:我正在使用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's scopes文档,他们会告诉我们为什么请求是一个范围本身以及如何处理它。但他们没有说明为什么转发时会创建子请求。
更多的谷歌搜索让我了解了事件监听器,在那里我了解到可以处理子请求(details)。好的,对于子请求类型,但这仍然无法解释为什么只删除用户请求。
我的问题变成了:
为什么在转发时删除用户请求而不复制用户请求?
答案 0 :(得分:1)
因此,控制器动作是逻辑的分离部分。这个功能对彼此一无所知。我的答案是 - 单一动作处理某种特定请求(例如,具有特定的uri prarams)。 来自SF2文档(http://symfony.com/doc/current/book/controller.html#requests-controller-response-lifecycle):
2路由器从请求中读取信息(例如URI),找到a 匹配该信息的路由,并读取_controller 来自路线的参数;
3来自匹配路线的控制器是 执行,控制器内的代码创建并返回一个 响应对象;
如果您的请求是针对路径/
,并且您想要处理此路由的内部操作(让我们说indexAction()
),请执行另一个控制器操作(例如fancyAction()
),您应该准备{{1 }} 为了那个原因。我的意思是使用(例如):
fancyAction()
代替:
public function fancyAction($name, $color)
{
// ... create and return a Response object
}
来自sf2 dosc的例子:
public function fancyAction()
{
$name = $this->getRequest()->get('name');
$color = $this->getRequest()->get('color');
// ... create and return a Response object
}
请注意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