ThinkPHP路由默认区分大小写,静态路由需完全匹配,动态变量和PATH_INFO大小写敏感,TP6控制器方法名强制转小写,须统一用小写下划线命名并显式路由映射。

ThinkPHP控制器路由默认区分大小写,但实际行为取决于路由定义方式、URL解析阶段和Web服务器配置——不是改一个配置就能全局生效,必须分层处理。
路由表达式本身是精确匹配的,不自动忽略大小写
Route::get('user/profile', 'user/profile') 这类静态路由,URL 中的 user 和 profile 必须与路由定义完全一致(包括大小写),否则 404。框架不会把 /User/Profile 自动转成小写再去匹配。
- 动态变量部分(如
user/:id)更敏感:若定义为User/:id,则只匹配大写开头的/User/123;写成user/:id就只认小写/user/123 - 正则路由可绕过:用
Route::rule('[a-zA-Z]+/[a-zA-Z]+', 'user/profile')能覆盖多种大小写组合,但需手动提取参数 - 不要依赖
url_convert:它只影响控制器/方法名的自动转换(如user_list→UserList),跟路由路径匹配无关
PATH_INFO 大小写统一要在框架加载前做
ThinkPHP 默认从 $_SERVER['PATH_INFO'] 提取路径,而这个值由 Web 服务器传递,原始大小写会被保留。想让所有路由“看起来不区分大小写”,必须在框架初始化前统一转小写。
- 在
app/common.php或public/index.php开头插入处理逻辑,仅对路径部分(?前)转小写,保留查询参数原样 - Apache 需确认
AcceptPathInfo On,Nginx 要检查fastcgi_split_path_info是否正确截取,否则PATH_INFO可能为空或错乱 - 此操作只影响路由匹配阶段,不影响控制器类名、方法名的真实大小写——它们仍需严格遵循 PSR-4 和框架约定
控制器方法名被强制转小写是 TP6 的固定行为
访问 /index/helloWorld 时,框架内部会把 helloWorld 转成 helloworld 再去查找方法,所以你写的 helloWorld() 永远不会被调用。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
立即学习“PHP免费学习笔记(深入)”;
- 这不是 bug,是
think\Route::parseUrlPath()的硬编码逻辑,无法通过中间件拦截修正 - 别改
vendor/topthink/framework/src/think/Route.php,升级后会被覆盖 - 正确做法是:控制器方法统一用小写下划线命名(如
hello_world()),并在路由中显式映射Route::get('index/hello-world', 'index/hello_world') - 资源路由(
Route::resource())也不支持 kebab-case 自动转驼峰,必须手动 bind 或重写规则
Windows 开发时路径大小写报错,本质是文件系统和加载机制冲突
Windows 下 IndexController.php 文件名小写、类名首字母大写(IndexController),看似能运行,但部署到 Linux 就报 Class not found——因为 PSR-4 自动加载器依赖文件系统大小写敏感性。
- 控制器文件名必须与类名完全一致:类
app\controller\UserProfile→ 文件必须是app/controller/UserProfile.php(注意大小写) - 模板引用也一样:
{include file="index/index"}中的路径大小写必须和view/下真实目录结构一致 - 禁用 opcache.file_cache_only(Windows 下易固化错误路径大小写)
- CI/CD 流程中加入校验脚本,用
is_file()检查所有控制器、模型、视图路径是否真实存在且大小写匹配
最易被忽略的是 PATH_INFO 的来源不可靠——本地开发跑通不代表线上没问题,得先看 $_SERVER['PATH_INFO'] 到底是什么,再决定在哪一层做标准化。盲目改框架源码或堆正则,只会让问题更难定位。


















