【问题标题】:symfony routing, use value from Request as defaultsymfony 路由,默认使用 Request 中的值
【发布时间】:2016-06-14 10:14:15
【问题描述】:

我有以下路线定义

my_route:
    path:               /actual-path/
    defaults:
        _controller:    MyBundle:MyController:detail
        id:             application_id
    requirements:
        methods:        GET
        id:             \d+

控制器需要一个名为$id的参数。

但我不想在 url 中使用 $id,我想使用 $request->attributes->get('application_id') 中可用的值

有一个监听器会在路由过程之前将两个参数(application_idapplication)作为属性注入到请求对象中,所以这个值就在那里。 (也很容易将其注入RequestContext)。

有没有一种方法可以在我的路由中使用来自RequestRequestContext 对象的属性值作为默认值?


现在我可以在我的控制器中简单地执行$request->attributes->get('application_id')。但是这个控制器会在几种情况下使用。在其他情况下,$id 将通过 url 传递。我发现在路由中设置 id 比在控制器中的某处构建 if-else 子句更干净。

【问题讨论】:

  • Controller::myAction(Request $request, $application_id) 会做你想做的事。控制器解析器将使用参数名称自动从请求对象中提取数据。你的问题有点混乱。如果 url 中不存在 id,则只需在 application_id 中添加您的侦听器。无论如何,我怀疑你的路线定义需要更多的工作。
  • 问题是,我无法更改控制器:操作,因为这是一个通用操作(位于供应商目录中)。所以控制器期待id,但Request中的值是application_id。所以基本上,我需要在路由配置中进行某种映射。
  • 我想你可以用表达式来做到这一点:symfony.com/doc/current/book/…。否则,请添加另一个内核侦听器来执行此操作。
  • 我已经在研究了,但我担心这也会变得有点混乱。我想我最好的机会是处理它是扩展控制器并在那里处理它。例如,如果 id === null,则使用 application_id。
  • 监听器很容易,特别是如果你有不止一条路线来处理这种事情。

标签: symfony symfony-routing


【解决方案1】:

似乎无法在请求对象中的变量与您的路由/控制器操作中需要的参数之间进行“映射”。我认为这将是一件好事,否则它会变得相当复杂。

我采用了扩展控制器并在那里构建一个小开关的解决方案。

基本上,如果路由指定id === null,它将回退到请求对象中的application_id。否则它将使用提供的值。我只需要在不能使用回退的路由上设置 id 的要求。

所有这些都无需运行额外的侦听器,这可能在处理时间上有点“昂贵”(对于每个请求)。

路线示例:

my_route:
    path:               /actual-path/
    defaults:
        _controller:    MyBundle:MyController:detail
        id:             null
    requirements:
        methods:        GET

my_other_route:
    path:               /other-path/{id}
    defaults:
        _controller:    MyBundle:MyController:detail
    requirements:
        methods:        GET
        id:             \d+

以及如何在你的控制器中处理这个问题:

    // fallback to system id
    if ($id === null) {
        $id = $request->attributes->get('administration_id', null);
    }

因为你扩展了控制器/动作,你也可以改变动作中的参数名称(只要类型不变)。

我没有这样做,因为我可以很容易地将提供的 id 和来自侦听器的后备之间的切换放在另一种方法中。

【讨论】:

  • 请注意,您可以为此使用现有的侦听器。订阅者可以在不同的时间收听不同的事件。但是任何适合你的都可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 2011-10-13
  • 2020-04-21
  • 2012-03-17
  • 1970-01-01
  • 2013-09-06
相关资源
最近更新 更多