param() 返回 null 的根本原因是路由定义错误,如缺冒号或花括号、参数顺序不匹配、正则约束过严、路由未生效或缓存未清除,而非框架或服务器问题。

param() 返回 null 或空值,根本原因几乎总是路由定义没写对占位符,不是框架 bug,也不是服务器配置问题。
路由规则里缺冒号或花括号
ThinkPHP 不会自动从 URL 路径段提取变量名。比如访问 /user/123,若路由写成 Route::get('user', 'index/User/read'),param('id') 一定为空。
- 正确写法必须显式声明:
Route::get('user/:id', 'index/User/read')(TP6/8)或Route::get('user/<id>', 'index/User/read')</id>(TP5) - 多个参数顺序必须严格匹配路径段:
user/:id/:type中param('type')拿到的是第二段,调换顺序就错乱 - 可选参数用
:id?或<id></id>,但不加?就是必填,匹配失败直接 404
param() 和 input() 混用导致取不到
input() 默认只读 $_GET 和 $_POST,完全不包含路由参数;input('get.id') 更错——:id 不在 $_GET 里。
- 安全取值统一用
param('id'),它自动合并路由、GET、POST、PUT 等来源 -
param()不能在控制器构造函数里调用,此时路由尚未解析,必定为空 - 中间件中若提前用了
input(),也可能拿不到,建议中间件也统一用param()
路由根本没生效,白写了
执行 php think route:list 是最直接的验证手段。如果输出里没有你写的那条带 /:id 的规则,说明路由文件没加载、位置错了,或开关被关了。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
立即学习“PHP免费学习笔记(深入)”;
- TP6/8:路由必须写在
app/route/app.php(单应用)或app/{app_name}/route/app.php(多应用),不是config/route.php - 确认
config/app.php中'app_route' => true是布尔true,不是字符串"true" - 改完路由后务必运行
php think route:clear清缓存,否则旧规则还在生效 - 伪静态没配好时,
/index.php/user/123能取到参数但去掉index.php就不行,说明问题在 Web 服务器重写规则,不是 PHP 层
正则约束太严或没加,导致匹配失败
写 user/:id 默认匹配任意非斜杠字符,但若加了 ->pattern(['id' => '\d+']),而实际 URL 是 /user/abc,整条路由就匹配不上,自然进不了控制器,param() 根本没机会执行。
- 中文、下划线、短横线等需显式放开:
[\x{4e00}-\x{9fa5}a-zA-Z0-9_-]+ - 约束只影响匹配阶段,不影响
param()取值逻辑;没加约束 ≠ 取不到,只是可能匹配到不该匹配的路径 - 调试时可临时去掉
->pattern(),确认是否约束本身导致路由未命中
最容易被忽略的一点:路由参数和查询字符串参数(?id=123)是两套机制。param('id') 能同时拿到路由段 /user/123 和查询串 ?name=think 里的值,但如果你只写了 Route::get('user', ...) 却指望 param('id') 拿到 ?id=123,那就混淆了语义——这种场景该用 input('id') 或 param('id') 都行,但前提是 URL 确实带了查询参数。


















