ThinkPHP语言自动侦测需同时开启lang_switch_on和lang_auto_detect,按GET→Cookie→Accept-Language固定顺序检测,且语言码必须在lang_list白名单内才生效,否则回退默认语言。

ThinkPHP 的语言自动侦测不是开箱即用的“智能识别”,它只按固定顺序检查三个来源:URL 参数、Cookie、浏览器 Accept-Language —— 且必须手动开启开关、配置允许列表,否则压根不触发。
lang_switch_on 和 LANG_AUTO_DETECT 必须同时为 true
仅设置 lang_switch_on = true 不够,LANG_AUTO_DETECT 也得显式开启。两者缺一,Lang::detect() 就不会执行,也不会读取任何外部信号。
- ThinkPHP 6.x 配置在
config/app.php中:'lang_switch_on' => true和'lang_auto_detect' => true - ThinkPHP 5.x 配置在
config.php或tags.php行为定义里,需确保'LANG_SWITCH_ON'和'LANG_AUTO_DETECT'均为true - 若只开
lang_switch_on而关lang_auto_detect,系统会直接跳过检测逻辑,始终用default_lang
语言侦测顺序固定:GET > Cookie > Accept-Language
ThinkPHP 按硬编码顺序检查,不会跳过中间项或合并结果。例如 URL 有 lang=ja-jp,哪怕 Cookie 是 think_lang=en-us,最终也生效日语。
- GET 参数键名由
VAR_LANGUAGE(TP6)或'VAR_LANGUAGE'(TP5)决定,默认是lang,但可改为l或language—— 改了就得统一用新键名传参 - Cookie 键名固定为
think_lang(TP6)或think_language(TP5),写错如lang或locale就完全失效 -
Accept-Language只取请求头第一个值(如zh-CN,zh;q=0.9,en-US;q=0.8→ 取zh-CN),且必须在LANG_LIST允许范围内才采纳
LANG_LIST 是硬性白名单,不在其中的语言一律回退默认
即使浏览器发来 Accept-Language: fr-FR,只要 LANG_LIST 没包含 fr-fr,系统就无视它,直接用 default_lang。
立即学习“PHP免费学习笔记(深入)”;
- TP6 配置格式为数组:
'lang_list' => ['zh-cn', 'en-us', 'ja-jp'] - TP5 配置格式为字符串:
'LANG_LIST' => 'zh-cn,en-us,ja-jp' - 大小写敏感:服务器上
zh-CN≠zh-cn,Linux 环境下路径匹配失败会导致语言包静默不加载 - 不设置
LANG_LIST时,部分版本会允许任意语言码,但行为不稳定,务必显式声明
Lang::detect() 不会自动重载语言包,且只运行一次
调用 Lang::detect() 仅返回侦测到的语言码(如 en-us),它本身不加载对应语言包,也不触发 Lang::setLang()。你得自己接续处理。
- 常见错误:在控制器里先
Lang::detect(),再lang('hello')—— 此时语言上下文仍是默认值,翻译无效 - 正确做法:在中间件中
Lang::setLang($lang),且必须在任何lang()或Lang::get()调用前完成 - Cookie 更新后不会自动触发重新 detect:改了
$_COOKIE['think_lang'],但请求已进入路由阶段,Lang 中间件不会再跑一遍
最易被忽略的是:语言侦测和语言包加载是两件事。Lang::detect() 只帮你“猜”出该用哪种语言,真正让 lang() 返回对应文本的,是提前调用的 Lang::setLang() 和目录结构正确的 lang/{lang}/common.php 文件 —— 少一个环节,整条链就断在静默里。



















