如何在 Symfony 中为控制器生成 URL?

How to generate an URL for a controller in Symfony?

我知道如何为路线生成 URL。但是现在我需要为控制器或带有方法的控制器生成一个 URL 。我查看了 UrlGenerator 的来源,但没有找到任何相关信息。 Symfony 文档中也没有信息。

控制器的方法有关联url。这个 url 将在控制器中使用,但我需要生成器作为服务。

基本上你需要:

1。添加路由到控制器

<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

final class BlogController extends AbstractController
{
    /**
     * @Route(path="blog", name="blog")
     */
    public function __invoke(): Response
    {
        return $this->render('blog/blog.twig');
    }
}

2。为路线

生成url路线

Symfony docs

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class SomeService
{
    /**
     * @var UrlGeneratorInterface
     */
    private $urlGenerator;

    public function __construct(UrlGeneratorInterface $urlGenerator)
    {
        $this->urlGenerator = $urlGenerator;
    }

    public function go()
    {
        // ...

        // generate a URL with no route arguments
        $signUpPage = $this->urlGenerator->generateUrl('sign_up');

        // generate a URL with route arguments
        $userProfilePage = $this->urlGenerator->generateUrl('user_profile', [
            'username' => $user->getUsername(),
        ]);


        // generated URLs are "absolute paths" by default. Pass a third optional
        // argument to generate different URLs (e.g. an "absolute URL")
        $signUpPage = $this->urlGenerator->generateUrl('sign_up', [], UrlGeneratorInterface::ABSOLUTE_URL);

        // when a route is localized, Symfony uses by default the current request locale
        // pass a different '_locale' value if you want to set the locale explicitly
        $signUpPageInDutch = $this->urlGenerator->generateUrl('sign_up', ['_locale' => 'nl']);
    }
}

所以,这是服务。至少是一个如何实施的例子。 SF4

namespace App\Route;

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouterInterface;

class UrlGenerator
{
    /**
     * @var RouteCollection
     */
    private $collection;

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

    public function generate(string $controllerClass, string $method): string
    {
        foreach ($this->collection as $item) {
            $defaults = $item->getDefaults();
            $controllerPath = $defaults['_controller'];
            $parts = explode('::', $controllerPath);

            if ($parts[0] !== $controllerClass) {
                continue;
            }

            if ($parts[1] !== $method) {
                continue;
            }

            return $item->getPath();
        }

        throw new \RuntimeException(
            'Route for such combination of controller and method is absent'
        );
    }
}

未经过充分测试但有效的解决方案。