必须在config/app.php中设置'lang_switch_on'=>true,否则多语言功能完全失效;语言目录名须小写短横线格式(如zh-cn),且必须在'lang_list'白名单中;lang()调用前须通过中间件调用lang::setlang()设好语言,路径、文件名、返回格式均需严格符合规范。

必须在 config/app.php 中显式开启 lang_switch_on,否则所有语言包、lang() 调用、URL 切换都无效——这不是可选功能,而是硬开关。
lang_switch_on 怎么配、配错会怎样
ThinkPHP 不默认启用多语言,哪怕你放好了 lang/zh-cn/common.php,没开开关就等于没写。
-
'lang_switch_on' => true是唯一生效条件,值为false或缺失,整个多语言机制直接跳过 -
'default_lang' => 'zh-cn'必须与语言目录名完全一致(小写、短横线),zh_CN或ZH-CN都不识别 -
'lang_list' => ['zh-cn', 'en-us']是白名单,不在其中的语言码(如zh-tw)即使有目录也不会被接受,Lang::setLang('zh-tw')会静默失败 - 常见错误:把配置写在
config/lang.php里——ThinkPHP 只认config/app.php里的多语言相关键
语言包路径和文件名必须严格遵循规则
ThinkPHP 按固定路径查找语言包,任意偏差都会导致 lang('xxx') 返回原 key 字符串(比如返回 'hello' 而不是 '你好'),且不报错。
- 根目录下建
lang/文件夹,不是language/、languages/或app/lang/ - 子目录名必须是小写语言码,如
lang/zh-cn/、lang/en-us/;lang/zh_CN/在 Linux 服务器上必然失效 - 文件必须是 PHP 脚本,返回数组,命名固定为
common.php(除非你手动指定分组);zh-cn.php或messages.json都不加载 -
lang/zh-cn/common.php内容必须以return ['hello' => '你好'];开头,不能有输出、不能用echo、不能漏return
lang() 函数调用前必须先设好语言,顺序错了就白搭
Lang::setLang() 不是“设置后全局永久生效”,它只影响当前请求后续的 lang() 调用。一旦 lang('xxx') 先执行了,再调 setLang() 也改不了这次的结果。
- 必须在中间件中设置,例如
app\common\middleware\Lang.php,且handle()方法里第一件事就读取并调用\think\Lang::setLang($lang) - 不要在控制器构造函数或
initialize()里设——中间件执行更早,此时语言已定型 - URL 参数
?lang=en-us能自动触发切换,但前提是lang_switch_on为true且lang_list包含该值;否则参数被忽略 -
lang('missing_key')默认返回'missing_key',容易误判为“生效了”,建议开发期加个兜底日志:if (lang('test') === 'test') trigger_error('语言包未加载')
动态切换时别依赖已加载内容,语言包不会重载
ThinkPHP 语言包是单次加载、常驻内存的。一次请求中调用 Lang::setLang('en-us') 后,lang() 返回英文没问题;但如果之前已加载过 zh-cn 的 common.php,它不会自动卸载或刷新。
- 所以切换动作必须在请求最开始做,确保所有
lang()都走新语言路径 - 不要试图在同一个请求里多次调
setLang()来“切来切去”——后一次不会覆盖前一次已解析的翻译项 - Session/Cookie 存语言选择没问题,但读取后必须立即
setLang(),不能等到模板渲染前才处理 - 如果用了模块化结构(如
app/admin/),模块内lang/admin.php优先于应用级lang/common.php,注意键名冲突
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











