lang::range() 是唯一能实时查看当前已加载全部语言变量的方式,它返回内存中 lang 类持有的真实键值对,不依赖缓存、不跳过未命中项,可精准定位语言包未加载等问题。

Lang::range() 是唯一靠谱的实时查看方式
Lang::get('xxx') 返回原 key 或空字符串,根本看不出是不是加载成功;Lang::range() 才能真实列出当前请求中已加载的所有语言变量键值对。它不依赖缓存、不跳过未命中项,返回的就是内存里此刻 Lang 类持有的全部翻译数据。
常见错误现象:Lang::get('user.name') 一直返回 'user.name',但你改了语言包死活不生效——十有八九是语言包压根没加载进来,而不是翻译错了。
-
Lang::range()必须在语言设置完成之后调用(比如中间件执行完、Lang::setLang()已触发),否则返回空数组 - 如果返回空,说明语言包路径错、文件名错、或
Lang初始化太晚(例如在控制器构造函数里才调Lang::setLang()) - 返回结果里没有你期望的 key,别急着改模板,先确认语言包是否被正确识别为「当前语言」:检查
Lang::getLangSet()输出是否是你预期的zh-cn或en-us
语言包路径和命名必须严格匹配 ThinkPHP 的解析逻辑
ThinkPHP 不会报错提示“语言包未找到”,只会静默跳过——这是调试时最头疼的点。它只认 lang/{lang}/common.php 或 lang/{lang}.php 这两种结构,且 {lang} 必须是小写、短横线分隔、无下划线(zh-cn ✅,zh_CN ❌,ZH-CN ❌)。
常见错误现象:lang/zh-cn.php 存在,但 Lang::get('hello') 仍返回 'hello';或者 Linux 服务器上一切正常,部署到另一台就失效。
- 确认路径是
app/lang/zh-cn/common.php,不是app/lang/zh-cn.php(后者只在旧版 TP3 中支持) - 文件内必须是
return ['hello' => '你好'];,不能套一层 locale 键:return ['zh-cn' => ['hello' => '你好']]会完全失效 - Linux 系统区分大小写,
Lang::setLang('ZH-CN')会导致后续所有语言包加载失败,且无任何 warning - 用
var_dump(Lang::getLangSet())和var_dump(Lang::isLoaded())配合看,前者告诉你当前设的是啥,后者告诉你有没有加载记录
切换语言后 Lang::get() 不刷新?问题出在加载时机
调用 Lang::setLang('en-us') 并不等于自动重载 lang/en-us/common.php。ThinkPHP 默认只在初始化阶段加载一次语言包,手动切换后,已加载的键值不会更新,新 key 更不会自动补上。
使用场景:用户点击语言切换按钮,前端发请求带 ?lang=en-us,后端收到后调 Lang::setLang(),但页面里还是中文。
- 必须在
Lang::setLang()后立刻调Lang::load(),传入绝对路径,例如:Lang::load(app()->getAppPath() . 'lang/en-us/common.php'); - 更稳妥的做法是统一在中间件里处理:读取
$request->param('lang')→ 校验白名单 →Lang::setLang($lang)→Lang::load(...) - 不要依赖
Lang::detect()自动加载,它只做探测,不负责 reload;尤其当语言来自 session 而非 URL 时,Lang::detect()根本不会触发 load - 第三方扩展的语言包(如
vendor/somepkg/lang/)默认不加载,必须显式Lang::load(EXTEND_PATH . 'somepkg/lang/zh-cn.php')
模板里 {:lang('key')} 显示原 key?检查作用域和中间件顺序
模板引擎调用 lang() 函数时,语言环境已经固定。如果中间件没在视图渲染前执行,或者中间件注册顺序靠后,lang() 就会 fallback 到默认语言甚至返回原 key。
常见错误现象:控制器里 Lang::get('hello') 正常,但模板里 {:lang('hello')} 显示 'hello';或者部分页面生效、部分不生效。
- 确认
think\middleware\LoadLangPack在middleware.php中排在靠前位置,不能被其他耗时中间件阻塞 - 若用了路由分组(如
lang/:lang),确保分组中间件里也调用了Lang::setLang(),否则子路由下语言环境仍是默认值 - 避免在模板中嵌套调用
lang(lang('key'))—— 第二层lang()会因作用域混乱返回空或原 key - 开启调试模式(
app_debug => true)后,缺失 key 会记入日志,但线上默认静默;上线前务必跑一遍Lang::range()对比各语言包完整度
Lang 类的行为高度依赖执行顺序、路径规范和加载时机——错一个环节,整个链条就断在看不见的地方。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











