Symfony 5动态路由解析
我正在将遗留项目路由(Yii1)迁移到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'
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'
不确定这是否是最好的方法,但似乎更简单。想到的另一个选择是挂接到服务器本身