ThinkPHP不支持语言包自动重载,需通过Lang中间件在请求开始时按优先级(GET→Cookie→Header→HTTP_ACCEPT_LANGUAGE)正确加载指定语言包,并确保路径、命名、大小写严格规范,且Lang::setLang()必须在首次翻译调用前执行。

必须启用并正确注册 Lang 中间件
系统不会自动加载语言包,Lang 中间件是触发加载的入口:
- 打开 app/middleware.php,确保包含:
'think\middleware\Lang'(ThinkPHP 6.0+ 推荐写法;V6.0.3+ 也可用'think\middleware\LoadLangPack',但需确认版本兼容性) - 该中间件必须放在
SessionInit之后、路由执行之前,否则无法读取 Cookie 或 Session - 多应用模式下,每个应用的
middleware.php都要单独添加
语言侦测顺序与配置对齐
ThinkPHP 按固定优先级侦测语言:GET 参数 → Cookie → Header → HTTP_ACCEPT_LANGUAGE。需在 config/lang.php 中显式开启并匹配前端传参方式:
-
'detect_var' => 'lang'→ 支持?lang=en-us强制切换 -
'use_cookie' => true且'cookie_var' => 'think_lang'→ 写 Cookie 必须用cookie('think_lang', 'en-us'),不能手写setcookie() -
'header_var' => 'think-lang'→ 前端请求头设think-lang: zh-cn -
'allow_lang_list' => ['zh-cn', 'en-us']→ 不在此列表的语言一律回退到default_lang
语言包路径与命名严格规范
路径错一个字符,就静默失败(不报错、不提示、只返回 key 名):
- 单应用模式:路径为 app/lang/zh-cn.php(不是
lang/zh_CN.php,不是app/lang/zh-cn/common.php,除非你启用了分组) - 文件内容必须以
return ['hello' => '你好'];开头,无 BOM、无空格、无 echo - Linux 服务器区分大小写:
zh-CN≠zh-cn,ZH-CN目录完全不可见 - 若使用扩展包(如
extend_list),路径也必须是真实可读的绝对路径,建议用app()->getBasePath() . 'lang/en-us.php'
动态切换必须在请求最开始执行
Lang::setLang() 或 Lang::setLocale() 只影响当前请求,且必须在任何 lang() 或 Lang::get() 调用前完成:
立即学习“PHP免费学习笔记(深入)”;
- ✅ 正确位置:自定义中间件的
handle()方法第一行,例如读 Session 后立即设置:\think\Lang::setLang($request->session('lang', 'zh-cn')); - ❌ 错误位置:控制器构造函数、Action 方法内、模板中 —— 此时语言包早已加载完毕,设置无效
- ⚠️ 注意:设置语言不会自动重写 Cookie,如需持久化,需额外调用
cookie('think_lang', $lang)



















