Lang::get() 返回空字符串是因为语言包未加载成功而非配置失效;需检查路径格式、中间件注册、lang/zh-cn.php存在性、BOM头、数组返回及MultiApp重复加载等问题。

Lang::get() 返回空字符串,不是配置没生效,而是语言包根本没加载成功——回退行为是静默的,不报错、不提示,只默默用默认语言或空值顶上。
Lang::get() 为空时,优先检查语言包是否真被加载了
ThinkPHP 不会因为键不存在就报错,而是直接返回空字符串。你看到空,大概率是语言包压根没进内存。
- 确认
lang/zh-cn.php路径存在且可读(注意是短横线zh-cn,不是zh_CN或zhcn) - 语言包必须 return 一个数组,不能有 BOM 头、不能有 echo/print 输出
- 用
Lang::range()打印当前已加载的所有键,比猜更直接:如果返回空数组,说明没加载;如果返回部分键,说明只加载了部分包 - 多应用模式下,
app/admin/lang/zh-cn.php和app/api/lang/zh-cn.php是独立路径,别漏掉子应用目录
中间件未注册或顺序错,会导致整个语言加载流程跳过
Lang 中间件不注册,等于没写。它不报错,但后续所有 Lang::get() 都在默认语言上下文中运行。
- 检查
app/middleware.php是否包含'think\middleware\Lang'(不是注释状态) - 多应用模式需在对应应用的
middleware.php中单独注册 - 中间件顺序必须在
SessionInit之后、路由解析之前,否则读不到$_COOKIE['think_lang'] -
think_lang是硬编码 Cookie 键名,设成lang或language都无效
自动侦测失效、URL 切换不持久,本质是语言上下文没延续
切换语言后刷新页面又回退,默认语言“赢”了——不是侦测逻辑坏了,是每次请求都重新走一遍检测,而检测源(Cookie / URL 参数)没保留。
立即学习“PHP免费学习笔记(深入)”;
-
Lang::set('en-us')只改本次请求上下文,不写 Cookie;要持久化必须手动cookie('think_lang', 'en-us') - URL 参数
?lang=en-us仅当config/lang.php中'detect_var' => 'lang'且'lang_switch_on' => true才生效 - 多应用模式下,
MultiApp.php会重复调用loadLangPack(),导致第二次加载覆盖第一次选择,临时解法是注释掉该行:// $this->app->loadLangPack(...) - 浏览器 Accept-Language 自动匹配依赖
config/lang.php中的'accept_language'映射表,没配就无法转译
兜底值写法错误,会让多语言变成“单语言盲跑”
嵌套结构不一致、平铺键名、JSON 字段直取——这些都会让 Lang::get('user.name') 永远拿不到值。
-
Lang::get('user.name')要求语言包里是return ['user' => ['name' => '用户名']],写成'user_name' => '用户名'就失效 - 用 JSON 存多语言字段(如
{"zh-cn": "标题", "en-us": "Title"}),得配合 accessor +Lang::getLangSet()动态取值,不能在 where 条件里直接用 - 扩展包语言文件(如 vendor/xxx/lang/zh-cn.php)不会自动加载,必须在中间件或
app/common.php里显式调用Lang::load(EXTEND_PATH . 'xxx/lang/zh-cn.php') - 切语言后
Lang::getLangSet()返回当前语言标识,但Lang::range()不会自动重载——换语言后要重新触发语言包加载,否则仍用旧缓存
最常被忽略的是语言包路径格式和中间件注册状态:一个写成 lang/zh_CN.php,一个忘了在 middleware.php 里加 Lang,就能让整套多语言静默瘫痪。调试时先打 Lang::range(),再查 Cookie 和中间件,比翻文档快得多。



















