如何以编程方式提供 Symfony 路由参数?
How to provide Symfony routing parameter programatically?
在这条 Symfony 路线中
/**
* @Route("/board/{board}/card/{card}", name="card_show", methods={"GET"}, options={})
*/
public function show(Board $board, Card $card): Response
{
$card->getLane()->getBoard(); // Board instance
// ...
}
如何以编程方式添加 {board}
参数,因为它已在 {card}
中可用?现在,我总是需要添加两个参数,当生成链接以显示操作时。
经过一些研究,我找到了 RoutingAutoBundle (https://symfony.com/doc/master/cmf/bundles/routing_auto/introduction.html#usage),它可以提供我需要的功能,但它不再适用于 Symfony 5。
谢谢。
好的,经过一些调查我发现 this question
这让我想到了 helpful answer.
我的控制器操作(带有 @Route
注释)如下所示:
/**
* @Route("/board/{board}/card/{card}", name="card_show", methods={"GET"})
*/
public function show(Card $card): Response
{
}
我们在方法签名中只有一个参数 ($card
),但在路由中有两个参数。
这是在twig中调用路由的方法:
path("card_show", {card: card.id})
不需要 board
参数,多亏了自定义路由器。
这是自定义路由器的样子:
<?php // src/Routing/CustomCardRouter.php
namespace App\Routing;
use App\Repository\CardRepository;
use Symfony\Component\Routing\RouterInterface;
class CustomCardRouter implements RouterInterface
{
private $router;
private $cardRepository;
public function __construct(RouterInterface $router, CardRepository $cardRepository)
{
$this->router = $router;
$this->cardRepository = $cardRepository;
}
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
{
if ($name === 'card_show') {
$card = $this->cardRepository->findOneBy(['id' => $parameters['card']]);
if ($card) {
$parameters['board'] = $card->getLane()->getBoard()->getId();
}
}
return $this->router->generate($name, $parameters, $referenceType);
}
public function setContext(\Symfony\Component\Routing\RequestContext $context)
{
$this->router->setContext($context);
}
public function getContext()
{
return $this->router->getContext();
}
public function getRouteCollection()
{
return $this->router->getRouteCollection();
}
public function match($pathinfo)
{
return $this->router->match($pathinfo);
}
}
现在,缺少的参数 board
是通过注入和使用卡片存储库以编程方式提供的。要启用自定义路由器,您需要在 services.yaml:
中注册它
App\Routing\CustomCardRouter:
decorates: 'router'
arguments: ['@App\Routing\CustomCardRouter.inner']
在这条 Symfony 路线中
/**
* @Route("/board/{board}/card/{card}", name="card_show", methods={"GET"}, options={})
*/
public function show(Board $board, Card $card): Response
{
$card->getLane()->getBoard(); // Board instance
// ...
}
如何以编程方式添加 {board}
参数,因为它已在 {card}
中可用?现在,我总是需要添加两个参数,当生成链接以显示操作时。
经过一些研究,我找到了 RoutingAutoBundle (https://symfony.com/doc/master/cmf/bundles/routing_auto/introduction.html#usage),它可以提供我需要的功能,但它不再适用于 Symfony 5。
谢谢。
好的,经过一些调查我发现 this question 这让我想到了 helpful answer.
我的控制器操作(带有 @Route
注释)如下所示:
/**
* @Route("/board/{board}/card/{card}", name="card_show", methods={"GET"})
*/
public function show(Card $card): Response
{
}
我们在方法签名中只有一个参数 ($card
),但在路由中有两个参数。
这是在twig中调用路由的方法:
path("card_show", {card: card.id})
不需要 board
参数,多亏了自定义路由器。
这是自定义路由器的样子:
<?php // src/Routing/CustomCardRouter.php
namespace App\Routing;
use App\Repository\CardRepository;
use Symfony\Component\Routing\RouterInterface;
class CustomCardRouter implements RouterInterface
{
private $router;
private $cardRepository;
public function __construct(RouterInterface $router, CardRepository $cardRepository)
{
$this->router = $router;
$this->cardRepository = $cardRepository;
}
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
{
if ($name === 'card_show') {
$card = $this->cardRepository->findOneBy(['id' => $parameters['card']]);
if ($card) {
$parameters['board'] = $card->getLane()->getBoard()->getId();
}
}
return $this->router->generate($name, $parameters, $referenceType);
}
public function setContext(\Symfony\Component\Routing\RequestContext $context)
{
$this->router->setContext($context);
}
public function getContext()
{
return $this->router->getContext();
}
public function getRouteCollection()
{
return $this->router->getRouteCollection();
}
public function match($pathinfo)
{
return $this->router->match($pathinfo);
}
}
现在,缺少的参数 board
是通过注入和使用卡片存储库以编程方式提供的。要启用自定义路由器,您需要在 services.yaml:
App\Routing\CustomCardRouter:
decorates: 'router'
arguments: ['@App\Routing\CustomCardRouter.inner']