ThinkPHP语言侦测顺序固定不可变:GET参数→Cookie→请求头→Accept-Language,高优先级命中即止;可通过config/lang.php配置各渠道开关、变量名及允许语言列表,并用Lang::getLangSet()验证实际生效值。

ThinkPHP 的语言侦测顺序是固定的,不能更改,但可以精准控制各来源是否启用、变量名如何定义、以及如何避免冲突。关键不在于“改顺序”,而在于理解它、配置它、用好它。
语言侦测的固定优先级必须清楚
系统按以下不可变顺序检测语言: - GET 参数(如 `?lang=zh-tw`) - Cookie(如 `think_lang=zh-tw`) - 请求头(如 `think-lang: zh-tw`) - 浏览器 `Accept-Language` 自动解析(如 `zh-TW,zh;q=0.9` → 转为 `zh-tw`)高优先级一旦命中有效值,就不再往后查。比如 URL 带 lang=en-us,即使 Cookie 是 zh-cn,最终也用 en-us。
配置各渠道开关与变量名要匹配前端行为
在 `config/lang.php` 中统一管理:设置
detect_var控制 GET 变量名:'detect_var' => 'l'→ 支持?l=zh-tw切换(适合简洁 URL)'detect_var' => 'lang'→ 支持?lang=en-us(更通用)-
启用并确认 Cookie 行为:
'use_cookie' => true(必须开启)'cookie_var' => 'think_lang'(Cookie 名固定,不可自定义)立即学习“PHP免费学习笔记(深入)”;
自定义请求头字段:
'header_var' => 'X-Language'或'think-lang',前端需在 AJAX 请求中带上对应 header禁用某渠道?直接设为
false或空字符串:'use_cookie' => false'header_var' => ''
繁体中文(zh-tw)支持要注意大小写和连字符
ThinkPHP 对语言标签做标准化处理:取 `Accept-Language` 第一段,转小写,并把下划线 `_` 和空格替换成短横 `-`。所以:- 浏览器发送
zh_TW→ 自动转为zh-tw - 发送
zh-TW→ 也转为zh-tw - 但
ZHTW或tw不会被识别
确保你的语言包目录和文件名为 lang/zh-tw/,且 lang/zh-tw.php 存在。同时在 'allow_lang_list' 中显式加入 'zh-tw':
'allow_lang_list' => ['zh-cn', 'en-us', 'zh-tw'],
调试语言实际生效值最简单的方法
不要靠猜,用代码验证当前语言环境:-
在中间件或控制器开头加一行:
\think\facade\Log::info('Current lang:', ['lang' => \think\facade\Lang::getLangSet()]); -
或直接输出:
echo \think\facade\Lang::getLangSet(); // 返回类似 'zh-tw'
配合开启 'middleware_trace' => true(仅开发环境),响应头会出现 X-Middleware-Stack,确认多语言中间件(如 CheckLangBehavior)是否已执行。
不复杂但容易忽略



















