thinkphp语言包必须为lang/目录下小写连字符命名的子目录(如zh-cn)中的php文件(如common.php),返回关联数组,路径和文件名严格区分大小写,不支持json/yaml或config/lang.php。

语言包必须是 PHP 文件,返回数组,路径和命名严格区分大小写,否则完全不生效。
lang/ 目录结构和文件命名怎么定
ThinkPHP 不读 config/lang.php 或 JSON/YAML 文件,只认 lang/ 目录下的 PHP 语言包。路径规则如下:
- 根目录下建
lang/,不能是Lang/或language/ - 子目录名必须是小写语言码,如
zh-cn、en-us;zh_CN、ZH-CN均无效 - 每个子目录里放
common.php(默认分组),或按需命名如user.php、admin.php - 文件内容必须以
return [...];结尾,不能有输出、BOM 头、注释前置
常见错误:lang/zh-cn.php 这种扁平结构会被忽略;lang/zh-cn/COMMON.PHP 在 Linux 上因大小写敏感直接加载失败。
语言包内容格式和 key 写法要求
数组 key 是你在代码中调用的标识符,值是对应语言的翻译文本。关键限制:
- key 必须是字符串字面量,不能含空格、特殊符号或变量插值,如
'user_login_success'合法,'User Login Success'或$key非法 - 占位符只支持
{name}格式,不支持:name、%s或{{name}} - 复数语法用竖线:
'item|items',传入数字 1 时取左边,其他取右边 - 如果 key 不存在,
lang('missing_key')默认返回原字符串'missing_key',不是报错也不是空——线上静默,极易漏检
示例 lang/zh-cn/common.php:
return [
'welcome' => '欢迎,{name}!',
'file_count' => '共 {count} 个文件|共 {count} 个文件',
];
为什么 lang() 没反应?常见加载失效原因
语言包写对了,但 lang('welcome') 仍输出原 key,大概率是加载时机或路径没走通:
-
Lang::setLang()必须在任何lang()调用之前执行;放在控制器构造函数里就晚了,中间件才是正确位置 - 模块化项目中,语言包优先级是:模块
lang/→ 应用lang/→ 框架默认;若模块里没放zh-cn/common.php,不会自动 fallback 到应用层 - 开启调试模式时,缺失 key 会记日志;但生产环境默认不提示,建议上线前用脚本比对所有
lang()调用和各语言包 key 是否全覆盖 - Apache 下注意 .htaccess 是否误拦截了
lang/目录;Nginx 要确认 root 配置未导致路径解析错误
动态切换语言时,已渲染的内容为什么不更新
ThinkPHP 的语言包是请求级加载,不是运行时热替换。这意味着:
-
Lang::setLang('en-us')只影响该次请求后续的lang()调用,已执行过的翻译不会回溯刷新 - 模板中提前写的
{:lang('title')}如果在setLang()前已解析,就会沿用旧语言 - 没有“重载全部已翻译内容”的 API;唯一可靠方式是在中间件最开始就完成语言判定与设置
- 如果依赖 Session/Cookie 切换,确保中间件里读取的是当前请求态的值,而非缓存或上一次请求残留
最易被忽略的一点:语言切换本身不触发页面重绘,前端需配合跳转或刷新,后端无法单靠 setLang() 让整页语言实时变化。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











