php-Laravel Route变量限制为17个字符

在Laravel中,我试图实现在URL中具有可变数量类别的能力,其次是slug.例如:

www.trashaccount.com/category1/category2/slug

我在Laravel中使用路线模式来识别类别

Route::pattern('cat', '([-a-zA-Z0-9]+\/?)*');

演示/测试路线如下所示:

Route::get('test/{cat}/{slug}', function($cat, $slug) {
    $categories = explode('/', $cat);
    $i = 1;
    foreach($categories as $category)  {
        echo "category " . $i . ": " . $category . "<br>";
        $i++;
    }
    echo "slug: " . $slug . "<br>";
});

可以在www.trashaccount.com/test/{cat}/…/{slug}进行测试

该代码成功地提取了任意数量的长度可变的类别.例如,这有效:

http://www.trashaccount.com/test/cat1/cat2/cat3/abcdefghijklmnopqrstuvwxyzabcdevg/my-slug

中断之处在于最后一个元素{slug}的字符数.由于某些原因,任何超出17个字符的字符都会引发NotFoundHttpException.因此,这不起作用:

http://www.trashaccount.com/test/cat1/abcdefghijklmnopqr

但是,如果您只是删除“ r”(18h字符),它将起作用.

为了澄清(由于我的帖子在另一个论坛上被误解了),您可以键入任意多个类别,它们可以是任意长度(遵守HTTP限制),它们将被接受并处理.我标记为{slug}的最后一个元素不能超过17个字符,而不会引发NotFoundHttpException错误.

有人知道我在做什么错吗?

谢谢!

解决方法:

老实说,我觉得这种行为很奇怪.

我什么也没做,所以我开始研究Laravel的内部代码,看看有什么问题,我得出的结论是,如果路由的最后一部分长于17个字符,那么它将失败.

一切发生在Illuminate\Routing\Matching\UriValidator->matches() line 25年.

这是一些使用/ test / first-category / testingslug的调试打印:

preg_match("#^/assets/(?P(?!\.\.)(.*))$#s", "/test/first-category/testingslug");

// successful
preg_match("#^/test/(?P([-a-zA-Z0-9]+\/?)*)/(?P[^/]++)$#s", "/test/first-category/testingslug");

category 1: first-category
slug: testingslug

一切正常,直到我尝试使用超过17个字符的子弹为止.

我尝试使用/ test / first-category / testingslugmuchlonger:

preg_match("#^/assets/(?P(?!\.\.)(.*))$#s", "/test/first-category/testingslugmuchlonger");   

// fails
preg_match("#^/test/(?P([-a-zA-Z0-9]+\/?)*)/(?P[^/]++)$#s", "/test/first-category/testingslugmuchlonger");

preg_match("#^/assets/(?P(?!\.\.)(.*))$#s", "/test/first-category/testingslugmuchlonger");  

// fails again
preg_match("#^/test/(?P([-a-zA-Z0-9]+\/?)*)/(?P[^/]++)$#s", "/test/first-category/testingslugmuchlonger");

之所以重复,是因为框架会检查Illuminate/Routing/RouteCollection.php->match() line 141中是否存在具有相同路由但方法不同的替代路由.

现在,我尝试在单独的文件中调试这两个preg_matc():

$works = null;
preg_match("#^/test/(([-a-zA-Z0-9]+\/?)*)/([^/]++)$#s", "/test/first-category/testingslug", $works);
var_dump($works);

$fails = null;
preg_match("#^/test/(([-a-zA-Z0-9]+\/?)*)/([^/]++)$#s", "/test/first-category/testingslugmuchlonger", $fails);
var_dump($fails);

这就是他们的回报:

array(4) {
  [0]=>
  string(32) "/test/first-category/testingslug"
  [1]=>
  string(14) "first-category"
  [2]=>
  string(14) "first-category"
  [3]=>
  string(11) "testingslug"
}

array(0) {
}

我认为preg_match一定有问题(?).

上一篇:Laravel 5:使用Route :: delete删除用户记录,在RouteCollection.php中获取MethodNotAllowedHttpException


下一篇:php-Laravel使用正确的URL渲染视图