ThinkPHP6.0多语言切换不生效需按顺序排查:启用LoadLangPack中间件、规范语言包路径命名、正确配置lang.php、早期动态设置语言环境。

ThinkPHP6.0多语言切换不生效,通常不是某一处配错了,而是多个环节断链导致的——语言包没加载、中间件没启用、路径或命名不规范、配置作用域错位,任何一个卡点都会让 lang('xxx') 原样返回键名。下面按实际生效顺序,逐项排查和配置。
确保 LoadLangPack 中间件已启用
这是最常被忽略的前提:TP6 不会自动加载语言包,必须显式启用 think\middleware\LoadLangPack,否则所有配置都是摆设。
- 检查
app/middleware.php(根应用)是否包含:'think\middleware\LoadLangPack'::class - 多应用模式下(如
app/admin),还需单独检查app/admin/middleware.php是否存在且内容为:return ['think\middleware\LoadLangPack'::class]; - 该中间件必须排在 Session、Auth 等依赖语言环境的中间件之前,否则读不到
think_langCookie 或 Session 值
语言包路径与文件命名必须“零误差”
框架只认小写字母 + 短横线的标准格式,且 Linux 下路径严格区分大小写,错一个字符就找不到文件。
- 正确路径示例:
app/lang/zh-cn/common.php、app/admin/lang/en-us/user.php - 文件名必须是
zh-cn.php或zh-cn/common.php,不能是ZH-CN.php、zh_CN.php、zh.php -
common.php内容必须以return [];开头,不能有 BOM、空行、echo或var_dump - 多应用时,子应用默认只加载自己目录下的语言包(如
app/admin/lang/),不会自动继承app/lang/
lang.php 配置要落在正确位置并满足约束
配置不是写一次就全局生效,它按应用作用域隔离,且关键字段有强校验规则。
立即学习“PHP免费学习笔记(深入)”;
- 单应用:配置放在
app/config/lang.php - 多应用:每个子应用需独立配置,如
app/admin/config/lang.php -
default_lang必须是allow_lang_list中的某一项,例如:'default_lang'=>'zh-cn'且'allow_lang_list'=>['zh-cn','en-us'] -
detect_var设为'lang'后,URL 切换才有效:?lang=en-us;若设为'l',就得用?l=en-us -
use_cookie为true时,cookie_var(默认think_lang)才起作用
动态切换语言必须在请求早期完成
语言环境必须在第一个 lang() 调用前就设定好,否则本次请求全程使用 fallback 语言(通常是 default_lang)。
- 推荐在自定义中间件中处理,例如:
app/common/middleware/LangSwitch.php - 读取用户偏好(Session/Cookie/API Header),再调用
\think\Lang::setLang($lang) - 不要在控制器构造函数或方法里调用
setLang(),那时语言包可能已加载完毕 - 验证是否生效:在中间件中加日志,确认
$lang值正确且setLang()执行无误



















