【问题标题】:$this->forward looses the user's requested route?$this->forward 丢失用户的请求路由?
【发布时间】:2013-05-05 08:44:37
【问题描述】:

当用户被识别但进入主页 (/) 时,我想将管理员重定向到 /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 文档,他们讲述了为什么 request 本身就是一个作用域以及如何处理它。但是他们没有说明为什么在转发时会创建子请求。

更多的谷歌搜索让我了解了事件侦听器,在那里我了解到可以处理子请求 (details)。好的,对于子请求类型,但这仍然不能解释为什么刚刚删除了用户请求。

我的问题变成了:

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

【问题讨论】:

  • 您应该为此功能使用事件侦听器。事件侦听器可以处理即当具有 ROLE_USRR 的用户尝试为 ROLE_ADMIN 用户打开主页时的情况。您可以通过创建 FilterControllerEvent 侦听器并将其重定向到特定的控制器/操作来做到这一点。我希望这会有所帮助:stackoverflow.com/questions/12916439/…
  • 实际上,如果用户访问ROLE_ADMIN页面,防火墙会抛出403。管理员可以访问ROLE_USER的页面。无论如何,这个问题更笼统:例如,我可以根据接口实现从控制器或另一个控制器切换,forward 看起来很适合此类工作。如果forward更新请求,我真的不明白应该在什么情况下使用。

标签: php symfony routing request forward


【解决方案1】:

因此,控制器操作是逻辑的独立部分。这个函数对彼此一无所知。我的回答是 - 单个动作处理特定请求(例如,使用特定 uri prarams)。 来自 SF2 文档 (http://symfony.com/doc/current/book/controller.html#requests-controller-response-lifecycle):

2 路由器从请求中读取信息(例如 URI),找到一个 匹配该信息的路由,并读取 _controller 路由参数;

3 来自匹配路由的 控制器是 执行,控制器内部的代码创建并返回一个 响应对象;

如果您的请求是路径 / 并且您想在内部操作(比如说 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 2015-02-14
    相关资源
    最近更新 更多