php think route:list命令直接输出当前环境所有已注册路由的表格,包含rule、method、controller、middlewares四列,用于快速定位路由匹配问题,执行前需确保app_debug=true并清空runtime/route/缓存。

直接看 php think route:list 输出,比翻日志快得多;它能暴露所有已注册路由的路径、方法、绑定控制器及中间件,是定位“匹配错误”的第一现场。
用命令行查路由注册全貌
ThinkPHP 不会在请求失败时自动告诉你“哪条路由没配对”,但 php think route:list 会把当前环境加载的所有路由规则列成表格,包含 Rule、Method、Controller、Middlewares 四列——这才是你该盯的真相。
- 执行前先确保 APP_DEBUG = true 且 runtime/route/ 缓存已清(删掉整个目录),否则看到的是旧缓存
- 如果列表为空,说明路由文件根本没被加载:检查是否写在了
app/route/app.php(TP6+ 单应用),而不是config/route.php - 注意
Rule列是否带前导斜杠(如/user/:id),不带的话可能只匹配根路径下的子路径,导致深层 URL 失效 -
Method列若显示*,表示是Route::any()或未限定方法;若显示GET,POST,说明必须严格匹配请求方式
开启路由匹配过程日志
光看注册列表还不够,有时你需要知道“框架到底拿你的 URL 去匹配了哪些规则”。这时候得靠日志钩子,而不是等报错后再翻堆栈。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 在
app/route/app.php底部加一行:\think\App::hook('route_check', function ($rule, $url, $method) { \think\facade\Log::info('route_check', compact('rule', 'url', 'method')); }); - 这个钩子会在每次尝试匹配前触发,记录原始 URL、当前尝试的路由规则和请求方法,日志会出现在
runtime/log/下当天文件里 - 注意不要在生产环境长期开启,它会显著拖慢响应;调试完记得删掉或注释掉
- 如果日志里压根没出现
route_check,说明请求根本没进到路由阶段——问题出在服务器重写或入口路径上,不是路由定义本身
为什么 $request->route() 总是 null?
很多人想用 $request->route() 拿匹配结果,但在 TP6 中这方法根本不存在;$request 对象不持有路由信息,它只管原始 HTTP 数据。真正有效的对象是 think\route\RuleItem,但它只在路由匹配完成后才注入容器。
- 在控制器或路由闭包中可用:
app('think\route\RuleItem')—— 若返回 null,说明当前执行点早于路由解析(比如在全局中间件早期) - 别在
app/middleware.php的['http' => []]数组开头放中间件,那会比路由还早执行;要获取路由信息,要么挪到数组末尾,要么改用['route' => []]类型(TP6.1+ 支持) -
$ruleItem->getMatchedParam()返回的是类型转换后的值(如'id' => 123),而$request->param('id')可能含默认值或经过过滤,二者语义不同,别混用 - 资源路由(
Route::resource())生成的RuleItem->getRule()是完整字符串(如'admin/user/:id@PUT'),不是你注册时写的'user',别拿它去字符串比对
最常被忽略的一点:路由匹配失败的 404 页面,和服务器原生 404 是两回事。前者你能看到黄色调试页,说明请求进了框架;后者连那个页面都出不来,说明 Nginx/Apache 根本没转发给 public/index.php —— 这时候再怎么调 route:list 都没用,得先查服务器配置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










