Как получить типы параметров в маршруте не совершая запрос?

Хочу получить все названия и типы параметров всех маршрутов.

Названия указаны в пути маршрута /{region}/houses/{tag}

Типы указаны в методе контроллера

public function listForTag(RegionAlias $region, TagAlias $tag)

К примеру, если у меня такой маршрут

/**
 * @Route("/{region}/houses/{tag}", name="list_hourse_tag")
 */
public function listForTag(RegionAlias $region, TagAlias $tag, Request $request)

то по названию маршрута list_hourse_tag я хочу получить список

  • region: App\RegionAlias
  • tag: App\TagAlias

Штатных средств я не нашел. Может, кто-нибудь сталкивался с подобной потребностью?


Ответы (1 шт):

Автор решения: Иван Антонов

Смог реализовать с помощью класса ArgumentMetadataFactory. Мне нужны были только те параметры, которые реализуют интерфейс ParamInterface, что мне помогло избежать остальных сервисных параметров, таких как Request.

use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
use Symfony\Component\Routing\RouterInterface;

class ParamProvider
{
    /**
     * @var RouterInterface
     */
    private $router;

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

    /**
     * @param string $routeName
     * @return ArgumentMetadata[]
     */
    public function getParameterMetadata(string $routeName): array
    {
        $metadataFactory = new ArgumentMetadataFactory();
        $routes = $this->router->getRouteCollection();
        $params = [];

        $controller = $routes->get($routeName)->getDefault('_controller');
        list($controllerName, $actionName) = explode('::', $controller);
        $argumentMetadata = $metadataFactory->createArgumentMetadata([new $controllerName(), $actionName]);

        foreach ($argumentMetadata as $metadata) {
            if (in_array(ParamInterface::class, class_implements($metadata->getType()))) {
                $params[] = $metadata;
            }
        }

        return $params;
    }
}
→ Ссылка