伪静态下 ?lang=en-us 参数收不到,根本原因是 nginx 重写时漏传 $query_string;tp6 虽能解析 path_info 路由,但 lang 参数依赖完整查询字符串透传,否则 $_get['lang'] 为空,lang::getlangset() 只能 fallback 默认语言。

伪静态下 ?lang=en-us 参数为什么收不到
不是框架没识别,是 Nginx 重写时把 $query_string 漏掉了。TP6 的路由解析器能拿到 PATH_INFO,但语言参数(如 ?lang=zh-cn)必须靠完整查询字符串透传,否则 $_GET['lang'] 为空,Lang::getLangSet() 就只能 fallback 到默认语言。
常见错误配置:
-
rewrite ^(.*)$ /public/index.php?s=$1 last;—— 完全丢弃了原始?后面的内容 -
try_files $uri $uri/ /index.php;—— 缺少$query_string,导致所有 GET 参数丢失
正确做法是在 rewrite 或 try_files 的 fallback 路径末尾显式拼上 $query_string:
location / {
try_files $uri $uri/ /public/index.php?$query_string;
}
二级目录部署时 lang 参数被截断怎么办
比如站点实际访问路径是 https://example.com/myapp/,而你用了 try_files $uri $uri/ /public/index.php?$query_string;,Nginx 会把 /myapp/index/index?lang=ja 中的 /myapp 当作 URI 前缀,但 $query_string 不包含它——结果 $_SERVER['PATH_INFO'] 变成 /myapp/index/index,而框架只认 /index/index,lang 参数看似存在,实则路由匹配失败,语言检测流程压根没触发。
解决方案是统一用 rewrite 并手动剥离前缀:
location /myapp/ {
if (!-e $request_filename) {
rewrite ^/myapp/(.*)$ /myapp/public/index.php?s=$1&$args last;
}
}
注意两点:
-
&$args等价于?$query_string,确保原参数透传 - rewrite 目标路径必须和实际物理路径一致(
/myapp/public/index.php),不能省略/myapp/
Lang::getLangSet() 返回空或默认值的真正原因
框架语言检测是链式过程:GET → Cookie → Header → HTTP_ACCEPT_LANGUAGE,但前提是 GET 渠道真能拿到值。如果伪静态规则没传 $query_string,或者 config/lang.php 里 lang_detect_var 配错了名字(比如设成 'l' 却仍发 ?lang=),Lang::getLangSet() 就不会从 URL 获取。
检查项清单:
- 确认
config/lang.php中'lang_detect_var' => 'lang'(与 URL 参数名严格一致) - 确认该值在
'allow_lang_list'数组中,例如['zh-cn', 'en-us', 'ja-jp'] - 在
public/index.php开头加var_dump($_GET); die();,访问/index/index?lang=ja-jp,看输出里是否有lang键 - 若无,说明问题出在 Nginx 层;若有,再查框架配置是否被中间件拦截
PATH_INFO 和 QUERY_STRING 必须同时生效
TP6 默认靠 PATH_INFO 解析路由(如 /index/index),靠 QUERY_STRING 解析语言等辅助参数。两者缺一不可:没有 PATH_INFO,请求进不了路由分发;没有 QUERY_STRING,?lang= 就是空气。
宝塔用户最容易忽略的三处硬性要求:
-
fastcgi_param PATH_INFO $fastcgi_path_info;必须出现在location ~ \.php$块内,且前面有fastcgi_split_path_info ^(.+\.php)(/.+)$; - 站点「运行目录」必须设为
/public,否则DOCUMENT_ROOT错位,PATH_INFO解析基准偏移 - PHP 禁用函数不能含
putenv或ini_set,否则public/index.php开头的环境初始化失败,PATH_INFO 支持直接被禁用
验证是否双通:访问一个不存在路径(如 /xyz?lang=de-de),若返回 TP6 自带 404 页面且页面底部显示当前语言为 de-de,说明 PATH_INFO 和 QUERY_STRING 都已就位。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











