default_lang配置不生效的根本原因是语言包未加载,常见于loadlangpack中间件未注册、语言包路径格式错误(必须小写+短横线)、或lang::setlocale()调用时机过晚(应在初始化阶段而非控制器中)。

default_lang 配置不生效,根本不是配置写错了,而是语言包压根没加载——中间件没启用、路径不对、或切换时机太晚,三者占其一就静默失败。
LoadLangPack 中间件必须显式注册
ThinkPHP6 不会自动加载语言包,LoadLangPack 中间件一旦没注册,lang() 和 Lang::get() 就永远返回键名本身(比如 'welcome'),不报错也不提示。
- 打开
app/middleware.php,确认数组里有'think\middleware\LoadLangPack',不是注释状态,也不能写成字符串"think\middleware\LoadLangPack"(引号内命名空间在 PHP 8+ 可能触发 autoload 失败) - 多应用模式下,每个子应用的
app/{name}/middleware.php都要单独加,主应用配置不继承 - 中间件顺序很重要:它得在
SessionInit之后、路由调度之前执行,否则读不到 Cookie 或 Session 里的语言偏好
语言包路径必须严格小写 + 短横线格式
ThinkPHP6 按目录结构加载语言包,config/lang.php 里的 default_lang => 'zh-cn' 是“钥匙”,但钥匙只能开对锁——锁就是 app/lang/zh-cn/ 这个路径。大小写、下划线、斜杠方向错一个,就静默跳过。
- 正确路径:
app/lang/zh-cn/common.php、app/lang/en-us/validate.php - 错误示例:
app/lang/zh_CN/(下划线)、app/lang/ZH-CN/(大写)、app/lang/zhcn/(无短横线)、lang/zh-cn.php(文件而非目录) - 每个语言子目录下至少要有
common.php,内容为return ['welcome' => '欢迎'];,空文件或语法错误也会导致整个包加载失败
Lang::setLocale() 在控制器里调用完全无效
语言包在应用初始化阶段(think\App::init() 后、路由前)就一次性载入内存了。验证器、系统异常、validate.php 里的提示语句,全是在这个阶段绑定的。控制器里再调 Lang::setLocale('en-us'),只影响后续新调用的 lang(),对已加载的内容毫无作用。
- 典型表现:访问
en.example.com,但throw_exception(L('VALIDATE_ERROR'))仍输出中文 - 正确做法:在全局中间件(
app/middleware.php的handle()方法开头)用Config::set('lang.default_lang', $lang)覆盖配置,而不是Lang::setLocale() - 域名映射时,先用
parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST)清掉端口(避免localhost:8080匹配失败),再查config/lang_domains.php数组做映射
验证器错误信息仍是英文?validate.php 没加载或键名不匹配
验证器错误走的是 app/lang/{lang}/validate.php,不是 common.php,且键名必须和内置规则名完全一致——'require'、'email'、'max_length',一个字母都不能错,大小写敏感。
- 字段级提示要写成
'user_email.email' => '邮箱格式不正确',不能只写'email' => '...' - 静态验证
Validate::check()不触发自动加载,需手动Lang::load(app()->getAppPath() . 'lang/zh-cn/validate.php') - CLI 环境无自动侦测,命令入口开头就得加
Lang::setLocale('zh-cn')和Lang::load(...),否则一律 fallback 到en-us
最常被忽略的点:语言包路径大小写、中间件注册状态、以及验证器初始化时机——这三处任一出错,default_lang 都只是个摆设,框架连尝试加载的动作都不会有。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











