thinkphp多语言需严格遵循路径、命名和加载时机规范:语言包必须置于根目录lang/下,子目录全小写如zh-cn,文件返回数组;须在中间件中最早调用lang::setlang()完成加载,否则lang()返回原key。

ThinkPHP 多语言不是“引入”就能用的,语言包必须按约定路径存放、命名规范、且在翻译调用前完成加载,否则 lang() 返回原 key 字符串(比如 lang('hello') 直接输出 hello),看起来像没生效,其实根本没加载成功。
语言包必须放在 lang/ 目录下,且子目录名全小写
ThinkPHP 不认 config/lang.php、不认 Lang/(大写 L)、不认 zh_CN 或 ZH-CN。只接受 lang/zh-cn/common.php 这种结构。
-
lang/必须是项目根目录下的独立目录(非app/lang或application/lang) - 语言子目录名严格小写,
zh-cn≠zh-CN,Linux 服务器上大小写敏感,错一个字母就静默失败 - 文件必须返回数组,不能是 JSON/YAML,不能有额外输出(如 BOM、空行、
echo) - 常见错误:把语言包建在
app/common/lang/下却没配extend_list,框架压根不会扫这个路径
lang() 调用前必须已设置语言并完成加载
语言切换不是“全局配置一次就永久生效”,而是每次请求都需在最早时机确定语言并加载对应包。延迟设置会导致部分 lang() 调用仍走默认语言。
-
Lang::setLang('en-us')必须在任何lang()、L()、模板中{:lang('xxx')}之前执行 - 推荐在中间件中做,例如
app/middleware/Lang.php,读取$request->param('lang')或session('lang')后立刻调用Lang::setLang() - 不要在控制器构造函数里设 —— 中间件执行早于控制器实例化
- 不调用
Lang::detect()不会自动识别浏览器Accept-Language,它默认只看 URL 参数lang=和 Cookiethink_language
语言包加载顺序决定覆盖优先级
ThinkPHP 按固定顺序合并多个同名语言包,后加载的键会覆盖先加载的。搞错顺序就会导致自定义翻译被框架默认值顶掉。
- 加载顺序(从早到晚):
thinkphp/lang/zh-cn.php→lang/zh-cn/common.php→lang/zh-cn/user.php(如果存在) - 也就是说,你自己的
lang/zh-cn/common.php可以覆盖框架底层的提示语,但不能覆盖你自己在lang/zh-cn/user.php里定义的同名 key - 若用模块化结构(如
app/home/lang/zh-cn.php),需确认是否启用了模块语言包自动加载(默认不开启,需手动Lang::load())
最常被忽略的一点:语言包加载是“一次性”的 —— 同一请求中多次调用 Lang::setLang() 不会重新加载包,已缓存的翻译项不会刷新。所以务必在请求入口(中间件)就定死语言,别想着中途切换再重译。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











