宝塔面板一键部署ThinkPHP后,路由重写让我白加了两小时班
上周接了个小活,帮朋友把跑了两年的TP5项目迁到新服务器。想着宝塔现在支持ThinkPHP一键部署,应该能省点事,结果栽在了最不该栽的地方。
宝塔确实贴心,Nginx配置、运行目录指向public、伪静态规则一股脑全给你写好。我点完部署,上传代码,改好数据库配置,前台能跑通,心里还暗赞这工具链真成熟了。问题出在后台——所有带参数的路由全部404,比如 `/admin/user/edit/id/1` 这种,前台文章详情页倒是正常。
第一反应是TP6和TP5的路由语法差异,毕竟迁过来时顺手升了框架版本。对着文档查了半小时 `route.php`,`pathinfo` 配置也确认开了,`.htaccess` 都检查了两遍(虽然Nginx根本不走这个)。后来突然醒悟:宝塔自动写的伪静态规则里,只有最基础的那套 `try_files` 加 `rewrite`,它没处理 `PATH_INFO` 的传递。
具体点说,宝塔生成的规则长这样:
location / { if (!-e $request_filename){ rewrite ^(.*)$ /index.php?s=$1 last; break; } }
看着眼熟吧?很多教程里都是这套。但TP6在部分PHP-FPM配置下,`$_SERVER['PATH_INFO']` 要靠 `fastcgi_split_path_info` 切出来,或者显式在rewrite里保留。上面这规则只把路径丢给 `s` 参数,某些PHP版本/配置组合下,框架内部解析路由时 `PATH_INFO` 是空的,带参数的路由自然匹配不上。
我最后改成这样解决的:
location / { try_files $uri $uri/ /index.php$request_uri; }
或者更保守点,显式切分:
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; ... }
改完刷新,后台路由瞬间活了。这时候已经夜里十一点半,朋友催了三次微信。
事后复盘,这坑其实不算深,但"一键部署"给的幻觉太足,让人下意识觉得配套配置该是完备的。实际上宝塔那套通用规则照顾的是最常见场景,你的项目一旦有点年数、或者框架版本跨了代,伪静态这层几乎必查。我现在养了个习惯:不管用什么面板,部署完先打一条带三个以上层级参数的路由测试,比事后救火省太多时间。
另外提一嘴,如果你也遇到类似症状,别急着改代码,先 `phpinfo()` 里搜下 `PATH_INFO` 和 `ORIG_PATH_INFO` 有没有值,能快速定位是Web服务器层的问题还是框架层的问题。这俩变量空不空,决定你排查方向完全不同。