带有可选文件名部分的Laravel路由



通过下面的路由,我希望捕获sitemap.xmlsitemap-0.xml。但它只捕获sitemap-0.xml。你能帮我理解为什么它不起作用吗?

Route::get('/sitemap{suffix?}.xml', 'SitemapController@sitemap');

在控制器中,我这样做:public function sitemap($suffix = null)

当然,我可以制作一条名为Route::get('/sitemap.xml', 'FeedsController@sitemap');的额外路线,但这似乎是多余的。

如果您通过正则表达式对路由施加约束并使其成为可选的,那么它应该会起作用。请参阅以下路线示例:

<?php
Route::get('/sitemap{suffix?}.xml', 'SitemapController@sitemap')
->where('suffix', '-?([0-9]+)?');

为什么?

Laravel路线以Symfony路线为基础。路线中的可选部分不起作用,因为这是Symfony路线的工作方式。因此,如果可选部件之后有任何内容,Symfony Route将不匹配,因为它将成为必需的。

您已将路线定义为以下

'/sitemap{suffix?}.xml'

请注意,.xml是在可选部件之后使用的。所以现在需要这个部件{suffix?}。它必须有一些东西来代替suffix。这就是为什么sitemap.xml不起作用,而sitemap-01.xml起作用的原因。

新手解释

Symfony Route将为sitemap-09.xml路径生成以下正则表达式:

"{^/sitemap(?P<suffix>[^/.]++).xml$}sDu"

现在用括号包裹的部分,该部分称为命名捕获组

(?P<suffix>[^/.]++)

如果您想检查命名捕获组的骨架,则如下所示:

(?P<name>group)

这里,正则表达式的部分表示匹配任何,除了.xml之前的正斜杠(/(和点(.(。这意味着它匹配sitemap-0.xml或将匹配sitemap-0.xml中代替-0的任何内容。

因此,当您从sitemap-0.xml中省略-0时,部分(因为它不是可选的(在.xml之前没有任何匹配项。因此它与CCD_ 20不匹配。

为了解决这个问题,你应该像我上面所做的那样对路由设置一个约束,它会产生以下正则表达式:

"{^/sitemap(?P<suffix>-?(?:[0-9]+)?).xml$}sDu"

在这里,我告诉路由允许-[0-9]可选。因此,它与两者相匹配。

最新更新