我有一个使用注释在symfony2控制器中定义的路由。例如:
@Route("/{year}", name="show_list_for_user", defaults={ "year" = "2012" })
是否可以使默认年份动态化。也许从服务对象读取年份?
您可以在 RequestContext 中设置默认参数。
当Symfony生成一个URL时,它按以下顺序使用值:
请参阅Symfony'Component'Routing'Generator'UrlGenerator::doGenerate
:
$mergedParams = array_replace($defaults,
$this->context->getParameters(),
$parameters);
- 用户为生成 Url() 函数提供的参数
- 上下文参数
- 路由默认值
您可以在请求事件侦听器中设置上下文参数以覆盖路由默认值:
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"事件并设置请求属性(如果不存在)。
这是不可能的,但确实存在解决方法。创建一个处理默认情况的附加控制器。
方法 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;
}
恐
怕这是不可能的,默认值是静态的。
默认使用占位符,类似
defaults={ "year" = "CURRENT_YEAR" }
然后在控制器中执行以下操作:
if ($year == "CURRENT_YEAR") {
$year = //do something to find the current year
}
Ludeks 的 2023 版答案:
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);
}
}
}