1

在 PHP 中,klein 路由将匹配尽可能多的路由。我设置的 2 条路线相互冲突。他们是:

$route1: '/websites/[i:websiteId]/users/[i:id]?'

$route2: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]?'

这是我要匹配的 URL,我认为应该匹配第一个而不是第二个,是:

/api/v1-test/websites/100/users/4

为这两个生成的正则表达式是:

$regex1: `^/api(?:/(v1|v1-test))/websites(?:/(?P<websiteId>[0-9]++))/users(?:/(?P<id>[0-9]++))?$`

$regex2: `^/api(?:/(v1|v1-test))/websites(?:/(?P<websiteId>[0-9]++))/users(?:/(?P<filename>[0-9A-Za-z]++))(?:\.(?P<extension>json|csv))?$`

我的意思是如果没有“.csv”或“.json”,它就不匹配。问题是它匹配两条路线。对于第二个,生成的文件名是“4”,扩展名是空白的。

发送 /api/v1-test/websites/100/users/users.csv 可以正常工作,并且只匹配第二条路线。

我只能控制路线,而不是正则表达式或匹配。谢谢。

4

2 回答 2

0

这一点在这里

(?:\.(?P<extension>json|csv))?

在你的第二个正则表达式结束时,它会匹配是否有文件名,因为?在最后。问号的意思0 or 1 of the previous expression。摆脱它,至少,字符串只有在具有扩展名时才会匹配这个正则表达式。

要进行此更改,只需从第二条路线中删除问号,如下所示:

$route2: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]'
于 2013-04-13T00:22:29.737 回答
0

问题是match_type定义真的......很奇怪:

$match_types = array(
            'i' => '[0-9]++',
            'a' => '[0-9A-Za-z]++',
[...]

因此,您不能真正捕获[a-zA-Z]仅对应于...的序列我看到的唯一选择是使用 3 条路线:

$route1: '/websites/[i:websiteId]/users/[i:id]?'
$route2: '/websites/[i:websiteId]/users/[a:filename]'
$route3: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]'

并为路线 2 和 3 分配相同的操作。然后你会得到这个:

  • /api/v1-test/websites/100/users/与 1 匹配
  • /api/v1-test/websites/100/users/4与 1 匹配
  • /api/v1-test/websites/100/users/test与 2 匹配
  • /api/v1-test/websites/100/users/test.csv与 3 匹配

这似乎是您想要的行为。

另一种(更简单的)解决方案是利用以下文档:

路由自动匹配整个请求 URI。
如果只需要匹配请求URI的一部分
或使用自定义正则表达式,使用 @ 运算符。

然后,您可以像这样定义您的路线:

$route1: '@/websites/[0-9]+/users/[0-9]*$'
$route1: '@/websites/[0-9]+/users/[a-zA-Z]+(\.[a-zA-Z]+)?$'
于 2013-04-13T00:48:40.237 回答