Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony 5动态路由解析_Symfony_Url Routing_Fosrestbundle_Symfony5 - Fatal编程技术网

Symfony 5动态路由解析

Symfony 5动态路由解析,symfony,url-routing,fosrestbundle,symfony5,Symfony,Url Routing,Fosrestbundle,Symfony5,我正在将遗留项目路由(Yii1)迁移到Symfony 5 现在我的config/routing.yaml看起来像这样: -{path:'/login',方法:['GET'],控制器:'App\controller\RestController::actionLogin'} -{path:'/logout',方法:['GET'],控制器:'App\controller\RestController::actionLogout'} # [...] -{path:'/readme',方法:['GET'

我正在将遗留项目路由(Yii1)迁移到Symfony 5

现在我的
config/routing.yaml
看起来像这样:

-{path:'/login',方法:['GET'],控制器:'App\controller\RestController::actionLogin'}
-{path:'/logout',方法:['GET'],控制器:'App\controller\RestController::actionLogout'}
# [...]
-{path:'/readme',方法:['GET'],控制器:'App\controller\RestController::actionReadme'}
正如您所看到的,有大量重复的
url
操作的转换

是否可以根据某些参数动态解析控制器方法。例如

-{path:'/{action},方法:['GET'],控制器:'App\controller\RestController::action'}


一个选项是编写注释,但不知何故,这对我不起作用,并抛出
Route.php not found

控制器由
RequestListener
确定,特别是路由器。这又使用
UrlMatcher
来对照
RouteCollection
检查uri。您可以实现一个基于路由解析控制器的
匹配器。您所要做的就是返回一个带有
\u controller
键的数组

请注意,此解决方案不允许您从路由名称生成url,因为这是一个url,但您可以将其连接在一起

// src/Routing/NaiveRequestMatcher
namespace App\Routing;

use App\Controller\RestController;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
use Symfony\Component\Routing\RequestContext;

class NaiveRequestMatcher implements UrlMatcherInterface
{
    private $matcher;

    /**
     * @param $matcher The original 'router' service (implements UrlMatcher)
     */
    public function __construct($matcher)
    {
        $this->matcher = $matcher;
    }

    public function setContext(RequestContext $context)
    {
        return $this->matcher->setContext($context);
    }

    public function getContext()
    {
        return $this->matcher->getContext();
    }

    public function match(string $pathinfo)
    {
        try {
            // Check if the route is already defined
            return $this->matcher->match($pathinfo);
        } catch (ResourceNotFoundException $resourceNotFoundException) {
            // Allow only GET requests
            if ('GET' != $this->getContext()->getMethod()) {
                throw $resourceNotFoundException;
            }

            // Get the first component of the uri
            $routeName = current(explode('/', ltrim($pathinfo, '/')));

            // Check that the method is available...
            $baseControllerClass = RestController::class;
            $controller = $baseControllerClass.'::action'.ucfirst($routeName);
            if (is_callable($controller)) {
              return [
                '_controller' => $controller,
              ];
            }
            // Or bail
            throw $resourceNotFoundException;
        }
    }
}
现在您需要覆盖
侦听器
配置:

// config/services.yaml
Symfony\Component\HttpKernel\EventListener\RouterListener:
    arguments:
        - '@App\Routing\NaiveRequestMatcher'

App\Routing\NaiveRequestMatcher:
     arguments:
       - '@router.default'
不确定这是否是最好的方法,但似乎更简单。想到的另一个选择是挂接到服务器本身