默认语言由default_lang配置项决定,必须在config/app.php中显式设为语言包文件名(如'zh-cn'),且仅当lang_switch_on为true时作为兜底语言,实际优先按url参数、cookie、accept-language顺序加载。

默认语言由 default_lang 配置项决定,不改它就永远是 en-us —— 即使你放了中文语言包、开了多语言开关,页面照样显示英文。
在 config/app.php 里设置 default_lang
这是最直接、最优先生效的位置。ThinkPHP 6+ 的主配置文件路径通常是 config/app.php,必须在这里显式声明:
-
default_lang值必须是语言包文件名(不含扩展名),比如zh-cn对应lang/zh-cn.php - 不要写成
zh_CN、zh或Chinese,大小写和连字符必须完全匹配语言包命名 - 如果同时设置了
lang_switch_on => true,default_lang仅作为兜底语言,不是“初始语言”——实际加载顺序优先看 URL 参数、Cookie、Accept-Language - 配置示例(注意逗号和引号):
return [
'default_lang' => 'zh-cn',
'lang_switch_on' => true,
'allow_lang_list' => ['zh-cn', 'en-us'],
];
Lang::setLang() 动态覆盖默认语言的时机问题
这个方法能临时切换当前请求的语言,但它不会改变 default_lang 配置本身,也不影响后续请求。常见误用场景:
- 在中间件或控制器开头调用
Lang::setLang('en-us'),但语言包没加载完 → 翻译为空字符串 - 在视图渲染后才调用 → 已经输出的内容不会重译
- 没配合
Lang::load()手动加载目标语言包 → 尤其是自定义路径或分组语言时容易漏 - 正确做法:确保语言包已加载,且在任何
Lang::get()调用前执行
语言包路径和命名不匹配导致默认语言失效
ThinkPHP 按固定路径查找语言包,路径错一个字母、文件名少个 -,default_lang 就等于白设:
- 框架级语言包路径:
thinkphp/lang/zh-cn.php - 应用级语言包路径:
app/lang/zh-cn.php(TP6 默认位置)或application/lang/zh-cn.php(TP5) - 模块级语言包路径:
app/module/lang/zh-cn.php(只在对应模块下自动加载) - 文件必须返回数组,不能有输出、不能用 BOM 头,否则
require失败 → 回退到en-us - 验证是否加载成功:在控制器里打印
Lang::get('nonexistent_key'),如果返回空字符串,大概率是路径或文件名错了
开启 lang_switch_on 后 default_lang 反而“不生效”?
这是最容易被忽略的逻辑陷阱:只要 lang_switch_on => true,系统就会按顺序检测并优先采用以下任一来源的语言值:
-
$_GET['lang'](如?lang=en-us)→ 优先级最高 - Cookie 中
think_lang的值(可配cookie_var) -
$_SERVER['HTTP_ACCEPT_LANGUAGE']解析出的第一个语言标签
只有以上全部失败或值不在 allow_lang_list 中时,才回落到 default_lang。所以如果你测试时带了 ?lang=xx 或浏览器发了 Accept-Language: ja,default_lang 就永远不会触发。
真正要“强制默认”,要么关掉 lang_switch_on,要么确保所有自动检测入口都无效(清 Cookie、不传 lang 参数、浏览器语言设为允许列表内值),否则它只是个保底开关,不是启动开关。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











