我在web.php
中有以下路线:
Route::get('posts/{encoded_id}/{slug}', 'PostController@show')
...并且工作正常:
http://example.test/posts/1Dl89aRjpk/this-is-some-title
但是“问题”是,当我在路由参数的末尾添加空白 时,它也可以工作 {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
最后添加空格-这将正常工作,并且没有否 404:
Post::where('encoded_id', $encoded_id)->firstOrFail();
...但是为什么? 又如何使它失败(给出404)?
也许是因为数据库(CHAR
)中的字段类型?
$table->char('encoded_id', 10)
如果这就是原因-有什么办法可以在 databases.php
中配置MySQL,从而防止这种情况发生?
也许与.htaccess
有关(我正在使用XAMPP / Windows)?
我正在使用Laravel 5.6。
编辑:
我要问的是为什么会发生这种情况,如何防止这种情况发生,而不是如何修剪route参数。例如,在stackoverflow网址的question id
末尾添加空格,您将得到404:
https://stackoverflow.com/questions/51068436 /laravel-route-parameters-not-trimmed-it-normally-works-when-whitespace-is-added
答案 0 :(得分:2)
这是由于预期的SQL行为引起的。在您的控制器中,您将收到带有空格的完整$encoded_id
。 Laravel为您做的所有工作就是使用WHERE
调用SQL选择查询。 SQL在WHERE
比较中忽略尾随空格。
请参阅此question。
如果您想要404,请在ID中将空格替换为一些虚拟字符:
$encoded_id = str_replace(' ', '#', $encoded_id);
仅在确保ID不包含空格或井号的情况下,才执行此操作。
答案 1 :(得分:0)
基于balping的答案。其他一些解决方案是:
用#代替所有尾随空格
preg_replace("/\s+$/", "#", $encoded_id);
将修剪与str_pad和strlen结合使用。这将从前面和后面修剪空格,但是用#填充字符串,因此它仍然是原始长度。
str_pad(trim($encoded_id), strlen($encoded_id), '#');