Lang::get() 返回键名而非翻译值,主因是语言包未加载成功;需检查语言包路径、文件格式、中间件注册及加载时机,并用 dump() 和 error_log() 逐层验证。

Lang::get() 返回键名而不是翻译值?先确认语言包是否加载成功
这是最常见也最容易误判的问题:看起来配置全对,lang('welcome') 却始终返回 welcome。根本原因不是翻译函数失效,而是语言包压根没被加载进来。
实操建议:
- 在控制器或中间件里加一行调试:
dump(\think\Lang::isLoaded());—— 返回false就说明语言包加载链断了 - 检查
app/lang/zh-cn.php文件是否真的存在,且内容是return ['welcome' => '欢迎'];,开头不能有 BOM、空格、echo或注释 - 运行
php think lang:check(需自定义命令)或手动执行:dump(\think\Lang::load('zh-cn', 'common'));,看是否返回true - 注意:如果用了分组(如
admin/welcome),但语言包里没建admin键,Lang::get('admin/welcome')会静默失败,不报错也不回退
切换语言后页面没变?检查 Lang::setLocale() 的调用时机和白名单校验
直接改 $_GET['lang'] 或写 Cookie 后刷新页面没反应,大概率是 Lang::setLocale() 没在语言包加载前执行,或者传入了非法值导致被静默重置为默认语言。
实操建议:
- 在全局中间件(如
app/middleware.php)最前面插入调试代码:error_log('locale before: ' . \think\Lang::getLang()); - 切换时不要只做
\think\Lang::setLocale($request->param('lang')),必须加白名单校验:in_array($lang, config('lang.allow_lang_list')) - 设完 locale 后立刻 reload:
\think\Lang::load();,否则已缓存的翻译不会更新 - 别在控制器
__construct()里调setLocale()—— 此时中间件已执行完毕,语言环境已固化
插件内多语言失效?必须绕过主框架加载链,手动注入
插件(如 app/plugin/Pay/)里的 lang('pay_failed') 始终返回键名,是因为主应用的 LoadLangPack 中间件只扫 app/lang/,完全无视插件目录。
实操建议:
- 插件语言包路径必须是
app/plugin/Pay/lang/zh-cn/common.php,文件名小写+短横线,common.php里return [...] - 新建中间件
app/plugin/Pay/middleware/LangSwitch.php,handle()开头就取插件专属 Cookie:$lang = $request->cookie('plugin_pay_lang', 'zh-cn'); - 紧接着强制设置:
\think\Lang::setLocale($lang); \think\Lang::load($lang, 'common', 'app/plugin/Pay/lang'); - 确保该中间件注册在插件自己的
config.php的'middleware'数组里,且顺序靠前 - 前端切换按钮必须发请求到插件接口(如
/pay/setlang?lng=en-us),不能操作主站的think_langCookie
调试时发现语言反复重置?重点盯住 Cookie、Header 和 GET 参数的优先级冲突
你刚把语言切到 en-us,刷新一下又变回 zh-cn,往往是多个语言来源同时存在,而 ThinkPHP 的侦测顺序(GET → Cookie → Header → Accept-Language)导致低优先级来源被高优先级覆盖。
实操建议:
- 在中间件里打印所有输入源:
error_log('GET lang: ' . ($request->param('lang') ?: '-'));,error_log('Cookie lang: ' . ($request->cookie('think_lang') ?: '-')); - 临时禁用某一项:在
config/lang.php里设'use_cookie' => false,排除 Cookie 干扰 - 如果用了 Nginx 反向代理,检查是否透传了
Accept-Language头;某些 CDN 会删掉或固定这个 Header - 浏览器开发者工具 Network 面板里点请求 → Headers → 查看 Request Headers 是否含
think-lang: en-us,再看 Response Headers 是否带Set-Cookie: think_lang=en-us
语言包路径大小写、文件命名格式、中间件注册位置、加载时机这四点,任何一个出错都会让整个多语言流程静默失败——没有报错,只有键名原样返回。调试时别猜,先用 dump() 和 error_log() 把每一步的输入输出钉死。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











