ThinkPHP6路由踩坑之变量规则

发现了一个在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/1http://127.0.0.1:8000/user/resetPwd?id=1时会输出什么结果?

是不是app\controller\Index::read 1app\controller\Index::resetPwd 1呢?

答案是不。

进入到tp目录,执行php think run运行起来看一下

会发现结果是:app\controller\Index::read 1app\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 1app\controller\Index::resetPwd 1

1 条评论

发表评论

*