route()传参键名必须与路由占位符:id等完全一致,否则生成静态路径;可选参数需路由加?:且控制器设默认值;query参数须用第三参数传递;中文等特殊字符需pattern()正则约束。

route() 传参必须匹配路由定义里的变量名
route() 助手函数生成 URL 时,参数数组的键名必须和路由规则中 :xxx 占位符的名称完全一致,否则会退化成静态路径(比如只输出 /user/ 而不是 /user/123)。
常见错误现象:route('user/:id', ['uid' => 123]) → 生成 /user/;route('user/:id', []) → 同样是 /user/,不报错但缺值。
- 正确写法:
route('user/:id', ['id' => 123]) - 多个参数也一样:
route('article/:year/:month', ['year' => '2024', 'month' => '09']) - 如果路由是
user/:id/:name,就只能传['id' => 1, 'name' => 'foo'],顺序无关,但键名不能错
可选参数要用 /:xxx? + 默认值双重保险
想让某个路由参数真正可选(比如 /user/123 和 /user/123/edit 都匹配),光靠 /:type? 不够,控制器方法也得配默认值,否则一漏就 500。
例如路由定义为 Route::get('user/:id/:type?', 'User/profile'),对应方法必须写成:
public function profile($id = 0, $type = '') { ... }
注意:$type = null 不推荐,后续用 strlen($type) 会触发 warning;空字符串更安全。
-
/:xxx?表示 URL 路径段可省略,但 route() 调用时仍可传或不传该键 - 没传
type时,param('type')返回空字符串(因方法有默认值),而不是null - 若只写
/:xxx(无问号),则 route() 必须传,控制器方法也必须有对应参数(带默认值)
别把 query 参数当路由参数传给 route()
route() 只处理路径段里的 :xxx,不处理 ?a=1&b=2 这类 query string。想加查询参数,得用额外参数传数组:
错误写法:route('user/:id', ['id' => 123, 'from' => 'admin']) → from 被忽略,不会出现在 URL 中
正确写法:route('user/:id', ['id' => 123], ['from' => 'admin']) → 生成 /user/123?from=admin
- 第三个参数是 query 数组,专门用来拼接 ? 后面的部分
- 这个数组不参与路由匹配,只是附加输出,所以键名随意(
from、ref都行) - 如果路由本身含 query(如
user/:id?tab=info),TP 不支持这种写法——?在路由定义里会被当成字面量,不是语法糖
中文或特殊字符参数要配 pattern(),否则 404 或截断
默认 :name 只匹配 \w+(字母、数字、下划线),中文、斜杠、点号都会导致匹配失败或参数被截断。
比如访问 /article/你好世界,没加 pattern 时 param('title') 可能返回空或只拿到 你好。
解决方式是显式约束正则:
Route::get('article/:title', 'Index/read')->pattern(['title' => '\S+']);
-
\S+比[\w\u4e00-\u9fa5]+更稳妥,避免 Unicode 版本兼容问题 -
pattern()只对:xxx形式生效,对/:xxx?或 query 参数无效 - 正则太宽泛(如
.*)可能引发路由冲突,建议最小化匹配,比如[a-zA-Z0-9_\u4e00-\u9fa5\-]{2,50}
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











