是否可以在symfony2中动态设置路由的默认参数值?

问题描述 投票:0回答:5

我使用注释在 symfony2 控制器中定义了一条路由。例如:

@Route("/{year}", name="show_list_for_user", defaults={ "year" = "2012" })

是否可以使默认年份动态化。也许从服务对象读取年份?

php symfony url-routing
5个回答
11
投票

您可以在RequestContext中设置默认参数。

当 Symfony 生成 URL 时,它按以下顺序使用值:

参见

Symfony\Component\Routing\Generator\UrlGenerator::doGenerate

$mergedParams = array_replace($defaults,
                              $this->context->getParameters(),
                              $parameters);
  1. 用户向generateUrl()函数提供参数
  2. 上下文参数
  3. 默认路由

您可以在请求事件侦听器中设置上下文参数来覆盖路由默认值:

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Routing\RouterInterface;

class RequestListener
{
    private $_router;

    public function __construct(RouterInterface $router)
    {
        $this->_router = $router;
    }

    public function onRequest(GetResponseEvent $event)
    {
        $context = $this->_router->getContext();
        if (!$context->hasParameter('year')) {
            $context->setParameter('year', date('Y'));
        }
    }
}

服务配置:

<service id="my.request_listener"
         class="MyBundle\EventListener\RequestListener">

    <argument id="router" type="service"/>

    <tag name="kernel.event_listener"
         event="kernel.request" method="onRequest" />
</service>

这取决于用例,如果您想使用动态默认值只是为了生成 url,请使用上面的代码。如果您希望控制器在执行操作之前动态选择正确的默认值,您可以使用“kernel.controller”事件并设置请求属性(如果不存在)。


4
投票

这是不可能的,但确实存在解决方法。创建一个处理默认情况的附加控制器。

方法a - 转发请求

/**
 * @Route("/recent", name="show_recent_list_for_user")
 */
public function recentAction()
{
    $response = $this->forward('AcmeDemoBundle:Foo:bar', array(
        'year' => 2012,
    ));

    return $response;
}

方法b - 重定向请求

/**
 * @Route("/recent", name="show_recent_list_for_user")
 */
public function recentAction()
{
    $response = $this->redirect($this->generateUrl('show_list_for_user', array(
        'year' => 2012,
    )));

    return $response;
}

2
投票

恐怕这是不可能的,默认值是静态的。


2
投票

使用默认占位符,例如

defaults={ "year" = "CURRENT_YEAR" }

然后在你的控制器中执行如下操作:

if ($year == "CURRENT_YEAR") {
    $year = //do something to find the current year
}

0
投票

2023版Ludeks答案:


namespace App\EventListener;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Routing\RouterInterface;

#[AsEventListener(
    event: 'kernel.request',
    method: 'onRequest',
    priority: 0
)]
class RequestListener
{
    public function __construct(
        private readonly RouterInterface $router
    ) {
    }

    public function onRequest(RequestEvent $event): void
    {
        $context = $this->router->getContext();
        if (!$context->hasParameter('version')) {
            $context->setParameter('version', 1);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.