Laravel 未修剪路由参数(添加空格时正常工作)

Laravel Route Parameters Not Trimmed (it normally works when whitespace is added)

我在 web.php 中有以下路线:

Route::get('posts/{encoded_id}/{slug}', 'PostController@show')

...而且效果很好:

http://example.test/posts/1Dl89aRjpk/this-is-some-title

但是 "problem" 当我在路由参数末尾添加 white space 时它也会起作用 {encoded_id}:

http://example.test/posts/1Dl89aRjpk /this-is-some-title

// or

http://example.test/posts/1Dl89aRjpk%20 /this-is-some-title

// or

http://example.test/posts/1Dl89aRjpk%20%20 /this-is-some-title

在末尾添加白色space - 这将正常工作并且有 no 404:

Post::where('encoded_id', $encoded_id)->firstOrFail();

...但是 为什么? 我怎样才能让它失败(给出 404)?

可能是因为数据库中的字段类型 (CHAR)?

$table->char('encoded_id', 10)

如果这就是原因 - 有什么方法可以 databases.php 中配置 MySQL 以防止这种情况发生?

或者跟.htaccess有关系(我用的是XAMPP / Windows)?

我正在使用 Laravel 5.6。

编辑:

我问的是为什么会发生这种情况以及如何防止它发生,而不是如何 trim 路由参数。例如,在 Whosebug url 上的 question id 末尾添加白色 space,您将得到 404:

 /laravel-route-parameters-not-trimmed-it-normally-works-when-whitespace-is-added

这是预期的 SQL 行为。在您的控制器中,您会收到带空格的完整 $encoded_id。 Laravel 为您所做的一切,就是使用 WHERE 调用 SQL select 查询。 SQL 忽略 WHERE 比较中的尾随空格。

看到这个question

如果您想要 404,请将 ID 中的空格替换为一些虚拟字符:

$encoded_id = str_replace(' ', '#', $encoded_id);

只有在保证 ID 不包含空格或散列标记的情况下才执行此操作。

基于 balping 的回答。其他一些解决方案是:

将所有尾随空格替换为#

preg_replace("/\s+$/", "#", $encoded_id);

将 trim 与 str_pad 和 strlen 结合使用。这将 trim 前面和后面的空格,但用 #'s 填充字符串,因此它仍然是原始长度。

str_pad(trim($encoded_id), strlen($encoded_id), '#');