NestedMatcher
提供的 RequestMatcherInterface
实现是 NestedMatcher
。它适用于 DynamicRouter,并且它使用多步骤匹配过程来确定给定 Request 的最终路由参数。
NestedMatcher
使用 3 步匹配过程来确定在处理当前请求时要使用的路由
- 向
RouteProviderInterface
请求可能匹配Request
的Route
实例集合; - 应用所有
RouteFilterInterface
来过滤此集合; - 让
FinalMatcherInterface
实例决定剩余Route
实例中的最佳匹配,并将其转换为参数数组。
1. RouteProvider
尽管 RouteProviderInterface
可以以其他方式使用,但其主要目标是在 Doctrine PHPCR ODM 或任何其他数据库之上轻松实现,从而有效地允许您从数据库动态存储和管理路由。
基于 Request
,NestedMatcher
将从 Route Provider 检索 Route
对象的有序集合。此提供程序的想法是提供所有可能匹配的路由,但不执行任何详细的匹配操作 - 这将在后续步骤中完成。
提示
RoutingBundle 为使用 Doctrine PHPCR-ODM 以及 Doctrine ORM 运行此组件所需的一切提供了实现。
提示
此组件为在 /
上拆分 URL 的第一步提供了 Candidates
实现,以允许与可变模式匹配。
要创建和注册您自己的 Route Provider,请创建一个实现 Symfony\Cmf\Component\Routing\RouteProviderInterface
的类,该类将具有以下方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
use Symfony\Cmf\Component\Routing\RouteProviderInterface;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
class DoctrineOrmRouteProvider implements RouteProviderInterface
{
// ...
public function getRouteCollectionForRequest(Request $request)
{
// you should do some simple filtering on the URL here
$routes = $this->routeRepository->findAll();
$collection = new RouteCollection();
foreach ($routes as $route) {
$collection->add($route->getName(), $route);
}
return $collection;
}
public function getRouteByName($name, $parameters = array())
{
$route = $this->routeRepository->findByName($name);
if (!$route) {
throw new RouteNotFoundException("No route found for path '$name'");
}
return $route;
}
public function getRoutesByNames($names, $parameters = array())
{
return $this->routeRepository->createQueryBuilder('r')
->where("r.name IN (:names)")
->setParameter(':names', '"'.implode('","', $names.'"'))
->getQuery()
->getResult();
}
}
Route Provider 使用 NestedMatcher
构造函数的第一个参数设置
1 2 3 4 5
use Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher;
// ...
$routeProvider = new DoctrineOrmRouteProvider(...);
$nestedMatcher = new NestedMatcher($routeProvider, ...);
2. Route 过滤器
NestedMatcher
可以应用用户提供的 RouteFilterInterface
实现来减少提供的 Route
对象,例如,用于进行内容协商。如果集合中没有更多路由,则每个过滤器都有责任抛出 ResourceNotFoundException
。
过滤器通过实现 Symfony\Cmf\Component\Routing\NestedMatcher\RouteFilterInterface
来创建。它们可以使用 addRouteFilter
方法注册,该方法具有一个可选的第二个参数来设置优先级。
注意
过滤器步骤是可选的,专为特殊情况而设计。CmfRoutingBundle 默认不使用任何过滤器。
3. 最终匹配器
FinalMatcherInterface
实现必须找到恰好一个 Route,如果找不到合适的匹配项,则抛出异常。默认实现使用 Symfony Routing Component 的 UrlMatcher,并称为 Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher
。
您可以通过实现 Symfony\Cmf\Component\Routing\NestedMatcher\FinalMatcherInterface
来创建自己的最终匹配器。
最终匹配器使用 NestedMatcher
的构造函数的第二个参数设置
1 2 3 4 5
use Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher
// ...
$finalMatcher = new UrlMatcher(...);
$nestedMatcher = new NestedMatcher($routeProvider, $finalMatcher);