lang::get() 返回空字符串主因是语言包未加载成功,需严格匹配路径、命名(如zh-cn.php)、嵌套结构,且内容为return ['user'=>['name'=>'用户名']],utf-8无bom,v6不递归子目录。

Lang::get() 返回空字符串,90% 是语言包根本没加载成功,不是配置写错了,而是路径、命名、嵌套结构三者中至少一个不匹配。
lang/ 目录结构和文件命名必须严格按短横线格式
ThinkPHP 只识别 lang/zh-cn.php、lang/en-us.php 这类命名,zh_CN、zhcn、zh-cn/common.php 全部无效。v6 默认只扫描 lang/ 下一级的 PHP 文件,不递归子目录。
- 正确路径:
app/lang/zh-cn.php、app/lang/en-us.php - 错误示例:
app/lang/zh-CN.php(大小写敏感)、app/lang/zh_cn.php(下划线)、app/lang/zh-cn/common.php(多层结构) - 语言包内容必须是
return [...],不能有 BOM 头,用 UTF-8 无 BOM 格式保存
Lang::get('user.name') 要求语言包里是嵌套数组,不是平铺键名
如果你写 Lang::get('user.name'),语言包里必须返回 ['user' => ['name' => '用户名']];写成 'user_name' => '用户名' 就会返回空字符串,且无报错提示。
- 支持点号访问的前提:语言包结构必须与调用路径完全一致
- 调试时直接用
Lang::range()查看当前已加载的所有键,比翻文件更可靠 - 避免在语言包里混用点号和平铺写法,统一用嵌套结构更可控
切换语言后不生效?检查 Lang::setLocale() 的调用时机和位置
在中间件或控制器里调用 Lang::setLocale('en-us') 前,必须确保 Lang 类已完成初始化 —— 在 config 阶段或 common.php 里调用会静默失败。
- 推荐做法:在自定义中间件(如
app/middleware/LangSwitchMiddleware.php)中读取cookie('think_lang')或session('lang'),再调用Lang::setLocale($lang) - 如果用了路由分组(如
lang/:lang),记得从$request->param('lang')取值并透传,别只存 session 不设 locale - 确认
app.lang_switch_on为true,且app.default_lang是合法值(如'zh-cn'),否则整个链路不会启动
后台模板里用 {:lang('key')},但别依赖 URL 参数做唯一判断
ThinkPHP 默认通过 GET 参数 ?lang=en-us 触发切换,但用户从分享链接进来时可能没这个参数,而 session 或 cookie 里已有偏好 —— 此时应以存储状态为准,而非 URL。
- 模板中统一用
{:lang('title')}或{__('title')},不要手写 if-else 切换文案 - 控制器里避免重复设置:比如中间件已设好语言,控制器再调一次
Lang::setLocale()可能覆盖或冲突 - 第三方扩展(如插件)的语言包不会自动加载,需手动调用
Lang::load('/absolute/path/to/xx-lang.php')
最易被忽略的是语言包的加载时机和结构一致性 —— 它不像配置那样“写完就生效”,而是运行时动态加载、逐级匹配。一旦 Lang::range() 返回空数组,基本可以断定文件没被读到,立刻检查路径和命名。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











