发现了一个在ThinkPHP6路由使用上的坑,而且还是觉得像之前ThinkPHP3那种解析对应的控制器方法的好…
好了,言归正传,说一下到底是什么坑
首先我们安装一个新的Thinkphp代码来测试
composer create-project topthink/think tp
然后我们来定义两个路由
Route::get('user/:id', 'Index/read');
Route::get('user/resetPwd', 'Index/resetPwd');
在Index控制器中写入以下两个方法
public function read($id)
{
return sprintf('%s %s', __METHOD__, $id);
}
public function resetPwd()
{
$id = request()->get('id', 666);
return sprintf('%s %s', __METHOD__, $id);
}
先猜一下,当我们请求http://127.0.0.1:8000/user/1和http://127.0.0.1:8000/user/resetPwd?id=1时会输出什么结果?
是不是app\controller\Index::read 1和app\controller\Index::resetPwd 1呢?
答案是不。
进入到tp目录,执行php think run运行起来看一下
会发现结果是:app\controller\Index::read 1和app\controller\Index::read resetPwd
咦,为什么呢?我们路由不是定义的是resetPwd方法吗?为什么还走到了read方法中呢?
这个坑就是ThinkPHP中的变量规则,系统默认的变量规则设置是[\w\.]+,只会匹配字母、数字、中文和下划线字符
当我们请求/user/resetPwd?id=1就会匹配到所定义的user/:id,也就说把/resetPwd?id=1这一串当成了/:id匹配
那么如何解决这个问题呢?有两种解决方案。
1. 可以调整优先级,将user/resetPwd放到前面去
Route::get('user/resetPwd', 'Index/resetPwd');
Route::get('user/:id', 'Index/read');
2. 增加局部变量规则
我们可以给user/:id增加变量规则,限制它只能为数字
Route::get('user/:id', 'Index/read')
->pattern(['id' => '\d+']);
这时候再去请求的话,就会输出我们想要的结果了
app\controller\Index::read 1和app\controller\Index::resetPwd 1
任何个人或团体,未经允许禁止转载本文:《ThinkPHP6路由踩坑之变量规则》,谢谢合作!