如何实现ThinkPHP多语言支持以适配小程序国际化?
- 内容介绍
- 文章标签
- 相关推荐
本文共计882个文字,预计阅读时间需要4分钟。
ThinkPHP 是一款流行的 PHP 开源框架,它简化了 PHP 开发,提高了开发效率。以下是其基本功能和特点:
小程序请求必须带 lang 参数或自定义 header
小程序 wx.request 默认不会携带语言信息,服务端无法靠 $_SERVER['HTTP_ACCEPT_LANGUAGE'] 自动识别。必须在每次请求中明确传递:
- 推荐方式:URL 查询参数,如
/api/user?lang=zh-cn或/api/user?lang=en-us - 备选方式:自定义 header,如
lang: zh-cn,后端用input('server.HTTP_LANG')读取 - 避免用
storage存语言再拼 URL —— 请求失败时 lang 可能丢失,导致接口返回默认语言文案
Lang::setLocale() 必须在中间件里提前调用
ThinkPHP 的语言切换不是“全局变量赋值”,而是一次性初始化动作。如果在控制器里才调用 Lang::setLocale(),模板渲染或验证规则可能已按默认语言执行完毕。
- 在
app/middleware.php中注册中间件,例如CheckLangMiddleware - 中间件内优先读 URL 参数:
$lang = input('get.lang', cookie('lang') ?: session('lang')) - 校验是否在允许列表:
if (in_array($lang, Lang::getAllowLangList())) { Lang::setLocale($lang); } - 注意:不能在
config/app.php里直接调用Lang::setLocale()—— 此时 Lang 类尚未初始化,会静默失败
模板与 API 返回文案要统一用 lang() 函数
小程序前端通常只接收 JSON,所有提示文案(如表单错误、操作成功)都应由后端组装好再返回,不能让前端“自己翻译”。
立即学习“PHP免费学习笔记(深入)”;
- 控制器中不要写死字符串:
return json(['msg' => '用户名不能为空']); - 应改为:
return json(['msg' => lang('user.name.require')]); - 验证规则也需语言化:
['name', 'require|alphaNum', lang('user.name.require') . '|' . lang('user.name.format')] - 确保语言包键名嵌套结构一致:
lang/zh-cn.php中是['user' => ['name' => ['require' => '用户名不能为空']]],不能平铺为'user_name_require' => '...'
小程序登录态下语言偏好要持久化到服务端
小程序没有传统 Cookie,但用户语言选择需要跨请求保持。仅靠前端缓存不可靠(清除 storage 就丢),建议服务端绑定用户 ID 记录偏好。
- 首次设置语言时,把
$lang写入用户表的lang字段或独立偏好表 - 后续请求若未带
lang参数,则查库 fallback:$lang = $user ? $user->lang : config('default_lang'); - 避免只依赖小程序
wx.getSystemInfoSync().language—— 它返回的是系统语言(如zh_CN),而 ThinkPHP 只认zh-cn,需手动转换 - 转换示例:
$sysLang = str_replace('_', '-', strtolower(input('server.HTTP_LANGUAGE', '')));
最易被忽略的一点:小程序真机调试时,开发者工具模拟的 Accept-Language 不生效,必须手动加参数;而线上环境若忘了在中间件里读取 input('get.lang'),所有接口都会回退到 default_lang,且无任何报错提示。
本文共计882个文字,预计阅读时间需要4分钟。
ThinkPHP 是一款流行的 PHP 开源框架,它简化了 PHP 开发,提高了开发效率。以下是其基本功能和特点:
小程序请求必须带 lang 参数或自定义 header
小程序 wx.request 默认不会携带语言信息,服务端无法靠 $_SERVER['HTTP_ACCEPT_LANGUAGE'] 自动识别。必须在每次请求中明确传递:
- 推荐方式:URL 查询参数,如
/api/user?lang=zh-cn或/api/user?lang=en-us - 备选方式:自定义 header,如
lang: zh-cn,后端用input('server.HTTP_LANG')读取 - 避免用
storage存语言再拼 URL —— 请求失败时 lang 可能丢失,导致接口返回默认语言文案
Lang::setLocale() 必须在中间件里提前调用
ThinkPHP 的语言切换不是“全局变量赋值”,而是一次性初始化动作。如果在控制器里才调用 Lang::setLocale(),模板渲染或验证规则可能已按默认语言执行完毕。
- 在
app/middleware.php中注册中间件,例如CheckLangMiddleware - 中间件内优先读 URL 参数:
$lang = input('get.lang', cookie('lang') ?: session('lang')) - 校验是否在允许列表:
if (in_array($lang, Lang::getAllowLangList())) { Lang::setLocale($lang); } - 注意:不能在
config/app.php里直接调用Lang::setLocale()—— 此时 Lang 类尚未初始化,会静默失败
模板与 API 返回文案要统一用 lang() 函数
小程序前端通常只接收 JSON,所有提示文案(如表单错误、操作成功)都应由后端组装好再返回,不能让前端“自己翻译”。
立即学习“PHP免费学习笔记(深入)”;
- 控制器中不要写死字符串:
return json(['msg' => '用户名不能为空']); - 应改为:
return json(['msg' => lang('user.name.require')]); - 验证规则也需语言化:
['name', 'require|alphaNum', lang('user.name.require') . '|' . lang('user.name.format')] - 确保语言包键名嵌套结构一致:
lang/zh-cn.php中是['user' => ['name' => ['require' => '用户名不能为空']]],不能平铺为'user_name_require' => '...'
小程序登录态下语言偏好要持久化到服务端
小程序没有传统 Cookie,但用户语言选择需要跨请求保持。仅靠前端缓存不可靠(清除 storage 就丢),建议服务端绑定用户 ID 记录偏好。
- 首次设置语言时,把
$lang写入用户表的lang字段或独立偏好表 - 后续请求若未带
lang参数,则查库 fallback:$lang = $user ? $user->lang : config('default_lang'); - 避免只依赖小程序
wx.getSystemInfoSync().language—— 它返回的是系统语言(如zh_CN),而 ThinkPHP 只认zh-cn,需手动转换 - 转换示例:
$sysLang = str_replace('_', '-', strtolower(input('server.HTTP_LANGUAGE', '')));
最易被忽略的一点:小程序真机调试时,开发者工具模拟的 Accept-Language 不生效,必须手动加参数;而线上环境若忘了在中间件里读取 input('get.lang'),所有接口都会回退到 default_lang,且无任何报错提示。

