ThinkPHP多语言不加载的根源是框架未找到/读取/执行语言包,因路径、命名、注册、时机四条件缺一不可:路径须小写短横线(如app/lang/zh-cn.php),文件以return数组开头无BOM;Lang中间件需启用且置于SessionInit后;lang()前必须先setLocale;验证器提示需对应validate.php文件。

语言包不加载,不是代码写错了,而是框架根本没找到、没读到、没执行它。ThinkPHP 多语言机制非常依赖路径、命名、注册、时机这四个硬性条件,缺一不可,且任一环节出错都静默失败——lang('xxx') 返回原字符串或空值,不代表“生效了”,大概率是压根没加载。
检查语言包路径和文件名是否完全合规
ThinkPHP 对大小写和分隔符极其敏感,错一个字符就加载失败:
- 路径必须是小写字母 + 短横线,如 app/lang/zh-cn.php,不能是 app/lang/zh_CN.php、app/lang/zh-cn/index.php 或 app/lang/zh-cn/common.php(TP6 默认不认 common.php 后缀)
- 多应用模式下,路径为 app/应用名/lang/zh-cn.php,比如 app/admin/lang/en-us.php
- 文件必须以
return ['key' => '值'];开头,不能有 BOM、不能有空格、不能有echo或var_dump等任何输出 - Linux 服务器区分大小写,lang/ZH-CN/ 和 lang/zh-cn/ 是两个不同目录,后者才有效
确认 Lang 中间件已启用且位置正确
没有中间件,整个多语言流程就卡在第一步:
- 打开 app/middleware.php,确保数组中包含
'think\middleware\Lang'(TP6 推荐用此,非 LoadLangPack;若用后者需确认是否兼容当前版本) - 中间件顺序很重要:必须在
SessionInit之后、路由调度之前,否则读不到 cookie 或 session - 多应用模式下,每个应用的
middleware.php都要单独添加,不能只配主应用
验证语言配置与侦测逻辑是否匹配
语言切换靠的是“识别→设置→加载”链条,断在哪一环都会失效:
立即学习“PHP免费学习笔记(深入)”;
- 检查 config/lang.php 是否设置了
'default_lang' => 'zh-cn'和'allow_lang_list' => ['zh-cn', 'en-us'] - 确认 URL 参数名(如
?lang=zh-cn)与配置中'detect_var' => 'lang'一致 - Cookie 键名必须是 think_lang,前端设 cookie 要用
cookie('think_lang', 'zh-cn'),不能手动写document.cookie = "lang=zh-cn" - 语言侦测顺序固定:GET → Cookie → Header → HTTP_ACCEPT_LANGUAGE,优先级不可调,但可关掉某一项(如
'use_cookie' => false)
排查加载时机和作用域问题
语言包不是全局常驻,而是在请求生命周期中按需加载:
-
Lang::setLocale('zh-cn')或Lang::setLang('zh-cn')必须在 任何 lang() 调用前执行,控制器构造函数里设是无效的(中间件还没运行) - 验证器错误提示(如 require/email)走的是 app/lang/zh-cn/validate.php,不是 common.php;字段级提示要写成
'user_email.email' => '邮箱格式不对' - CLI 命令行环境无自动侦测,必须手动
Lang::setLocale('zh-cn')并Lang::load(...)加载对应文件 - 静态验证
Validate::check()不触发自动加载,需提前手动 load 语言包



















