小程序必须显式传入语言参数(如zh-cn),经标准化、校验后调用lang::setlang(),且需在首次lang()前执行;语言包路径须为lang/zh-cn/common.php,命名与格式严格小写短横线。

小程序端不能靠 Accept-Language 自动识别语言,也不能直接读取浏览器 Cookie,必须显式传入语言标识并手动设置,否则 lang() 永远返回默认语言的值。
小程序请求如何携带语言参数
前端在每次 API 请求 header 或 query 中带上当前语言码(如 zh-CN 或 en-US),推荐用 query 参数统一处理,例如:/api/user?lang=zh-CN。不要依赖小程序 getSystemInfo 返回的 language 字段直接拼成 zh_CN —— ThinkPHP 只认短横线格式,zh_CN 会被忽略。
- 小程序端获取语言:使用
wx.getSystemInfoSync().language,它返回类似zh_CN、en_US的值,需手动转成zh-cn、en-us - 后端不信任客户端传来的任意字符串,必须校验是否在
lang_list配置范围内 - 避免把语言参数塞进 header 如
X-Language后再自定义中间件解析——ThinkPHP 原生不支持,徒增维护成本
中间件里怎么安全设置语言
必须在所有业务逻辑执行前调用 Lang::setLang(),且不能晚于第一次 lang() 调用。最稳妥的位置是全局中间件(如 app\common\middleware\Lang.php)的 handle 方法开头。
- 从 request query 读取
lang参数:$lang = $request->param('lang', 'zh-cn') - 强制标准化格式:
$lang = strtolower(str_replace('_', '-', $lang)) - 校验合法性:
in_array($lang, config('app.lang_list', ['zh-cn', 'en-us'])) ?: 'zh-cn' - 立即设置:
\think\Lang::setLang($lang)—— 这行必须在$next($request)之前
为什么 Lang::get() 返回空或原 key
不是配置没开,而是语言包根本没加载成功。常见原因有三个:路径错、命名错、结构错。
- 路径必须是
lang/zh-cn/common.php,不能是lang/zh-cn.php(那是旧版写法,TP6+ 已弃用) - 文件名必须小写 + 短横线,
zh-CN、ZH-CN、zh_cn全部无效 -
common.php必须以return [...]结尾,不能有 BOM 头、不能有echo或多余空白输出 - 如果用了模块化结构,确认语言包放在对应模块的
lang/下,而非全局lang/—— 模块优先级更高,容易覆盖错
小程序模板里怎么用多语言文本
小程序本身不支持 PHP 模板语法,所以不能在 WXML 里直接写 {:lang('hello')}。所有多语言文本必须由后端接口返回,前端只做展示。
- 控制器里提前组装好带翻译的字段:
'title' => lang('product_title') - 避免在小程序端用 JS 做语言映射(如维护一个
dict = {zh: {...}, en: {...}}),会导致语言包重复、无法热更新 - 若需动态切换语言,小程序要重新请求一次接口(带新
lang参数),而不是仅改本地状态 - 注意:JSON 字段中存多语言内容时,键名必须和当前
Lang::getLangSet()严格一致,zh-cn和zh_CN是两个不同键
最容易被忽略的是语言码标准化这一步——小程序返回的 zh_CN 不经转换就传给 Lang::setLang(),框架静默失败,lang() 照样返回英文或默认值,日志里还不报错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











