如何以编程方式提供 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']