$ this-> forward丢失了用户的请求路由?

时间:2013-05-05 08:44:37

标签: php symfony routing request forward

我想在确定用户后将管理员重定向到/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)。好的,对于子请求类型,但这仍然无法解释为什么只删除用户请求。

我的问题变成了:

  

为什么在转发时删除用户请求而不复制用户请求?

1 个答案:

答案 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