【问题标题】:Laravel route inexplicably failingLaravel路线莫名其妙地失败
【发布时间】:2014-08-01 23:12:39
【问题描述】:

这个路由对于像http://localhost:8080/promos/130-unburdened.pdf这样的URL来说很好用

  Route::get('/{report_slug}/{report_code}{burdening_tag?}{extension?}', function($report_slug, $report_code, $burdening_tag='', $extension='') {
    return "report_slug: ${report_slug}<br>report_code: ${report_code}<br>burdening_tag: $burdening_tag<br>extension: $extension";
  });

但是如果我在{extension?}之前添加另一个可选参数,这是我真正需要的它会失败,无论如何:

Route::get('/{report_slug}/{report_code}{burdening_tag?}{something?}{extension?}', function($report_slug, $report_code, $burdening_tag='', $something='', $extension='') {
    return "report_slug: ${report_slug}<br>report_code: ${report_code}<br>burdening_tag: $burdening_tag<br>extension: $extension";
  });

所有可选参数都定义了模式,因此它们不能匹配错误的东西:

Route::pattern('report_code', '[0-9]+');
Route::pattern('burdening_tag', '(-burdened|-unburdened)');
Route::pattern('something', 'X');
Route::pattern('extension', '(\.pdf|\.xlsx|\.xls|\.csv)');
Route::pattern('report_slug',
  '(adplan|adplan-update|adplan-proof'
  .'|scandown'
  .'|promos|promo-updates'
  .'|promos-finance|promos-cost-proof'
  .'|retail-price-proof'
  .'|finance'
  .'|dsd-promos|managed-dsd-promos'
  .'|anchor-group)'
);

然而一个工作,另一个崩溃和燃烧。怎么了? Laravel 是否仅限于 2 个可选参数?这是 Laravel 的错误吗?

【问题讨论】:

  • 当然你不能有2个可选参数,至少不是你这样做的方式?见stackoverflow.com/questions/22649764/…stackoverflow.com/questions/22877725/…
  • 为什么不能有 2 个或更多可选参数?这些模式限制了它们,因此 Laravel 应该 匹配没有问题。
  • 我不想处理任意数量的无约束参数,例如第二个问题。而且我不确定第一个问题为什么或如何相关。
  • 它们都是关于多条可选路线,我认为这与您面临的问题相同
  • 我的非常不同,因为我指定了 完全 什么可以匹配(以及什么不能匹配)。在 #1 中,他有 2 个参数,但我可以让 2 个参数正常工作。

标签: php laravel


【解决方案1】:

因为存在歧义:在您的第一个路由中,此 URL http://localhost:8080/promos/130.pdf 应该不起作用,即使它应该与模式匹配。

让我用一个简单的例子来解释:

Route::pattern('foo', 'A');
Route::pattern('bar', 'B');
Route::get('/test/{foo?}{bar?}',function($foo='',$bar=''){
    return "foo: $foo <br> bar: $bar";
});
// http://localhost:8080/test/AB  => work
// http://localhost:8080/test/A   => work
// http://localhost:8080/test/B   => doesn't work

在第三个url中,foo参数不为空,但包含字母B(本例bar为空),所以它不匹配“foo模式”,因此NotFoundHttpException

我在你的情况下尝试什么(如果你指定 something 参数,效果很好)

Route::pattern('something', 'X?');
// other patterns 
Route::get('/{report_slug}/{report_code}{burdening_tag?}{something?}{extension?}', function($report_slug, $report_code, $burdening_tag='', $something='', $extension= '') {
    return "report_slug: ${report_slug}<br>report_code: ${report_code}<br>burdening_tag: $burdening_tag <br>something: $something <br>extension: $extension ";
});

但是如果没有指定something 参数(如第三个示例),$extension 将为空,$something 将是扩展名,因此您只需检查$extension 是否为空:

$realExtension = $extension ? $extension : $something;

我知道这很难看,但我真的没有一个好的答案,也许有人可以提供一个真正的答案。

【讨论】:

  • 但是$foo 不能 包含'B',因为Route::pattern 将其限制为'A',所以$foo 应该为NULL $bar 应该是“B”。否则模式的意义何在?所以我看不出有任何歧义。 /test/B 应该匹配路由并给你[$foo =&gt; NULL, $bar =&gt; 'B']
  • 你是说一个可选路由不能匹配如果之前的可选路由不匹配?如果是这样的话,我认为它可以解释问题,但它似乎是 Laravel 路由中的一个大洞,没有任何意义。
猜你喜欢
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多