laravel api 多语言必须显式设置 locale,通过 accept-language 或校验后的 locale 参数调用 app::setlocale(),否则 __() 恒用默认语言;lang 目录需严格按 lang/{locale}/messages.php 组织,json 响应前须完成 locale 切换。

直接说结论:Laravel API 实现多语言,不是靠 __('key') 自动识别浏览器语言,而是必须显式接收并验证客户端传来的语言标识(如 Accept-Language 头或 locale 参数),再用它切换 App::setLocale() —— 否则所有翻译都走默认 locale。
怎么让 __() 返回对应语言的翻译内容
API 不像 Web 请求有 session 或 cookie 自动带 locale,__() 默认只认 config('app.locale')。要让它动态响应,得手动干预:
- 在中间件或控制器开头调用
App::setLocale($locale),且$locale必须是已配置的合法值(比如en、zh_CN),不能直接信用户传的任意字符串 - 推荐从请求头
Accept-Language解析首选语言,但注意它可能含权重(如zh-CN,zh;q=0.9,en;q=0.8),得用request()->getPreferredLanguage(['en', 'zh_CN'])安全提取 - 如果允许 URL 参数覆盖(如
?locale=ja),务必校验该值是否在config('app.available_locales')白名单里,否则会触发InvalidArgumentException - 别在模型 accessor 或全局作用域里调用
__()—— 那里拿不到当前请求的 locale 上下文,容易返回错语言
lang/ 目录结构和文件命名怎么才不翻车
Laravel 对语言文件路径很敏感,稍不对就静默回退到默认语言,连报错都没有:
- 目录必须严格按
lang/{locale}/messages.php组织,{locale}是 config 里定义的 key,不是语言名(比如不能叫lang/chinese/,得是lang/zh_CN/) - 文件名必须是
messages.php(除非你改了trans('xxx')的默认组),其他名字如validation.php只在对应场景生效(表单验证错误),API 响应里用__('xxx')默认只查messages.php - 数组键名不要含点号以外的特殊字符,尤其避免空格或斜杠;
__('auth.failed')能工作,但__('auth login failed')会找不到 - 中文 locale 推荐用
zh_CN而非zh,因为 Windows 和部分安卓设备发的Accept-Language常带地区码,纯zh匹配率低
JSON 响应里嵌套翻译字段怎么保持一致性
API 返回 JSON 时,常需把翻译结果塞进数组字段(比如 "status": __("success")),这里容易漏掉 locale 切换时机:
- 必须在构造响应数组之前调用
App::setLocale(),而不是在return response()->json([...])里临时切 —— 因为__()是运行时求值,顺序错了就白设 - 如果用了 Eloquent Resource,别在
toArray()里写__('xxx'),而应在 resource 构造时传入 locale,或在 controller 里先 setLocale 再 new Resource - 对分页响应(
LengthAwarePaginator),其links()方法生成的 HTML 里也含翻译,但 API 场景不该返回 HTML,建议显式禁用:->withQueryString()->onEachSide(0),再手动拼接分页元数据 - 缓存翻译内容时(比如 Redis 存
zh_CN:login_success),记得 key 里带上 locale,别让不同语言共用一个缓存项
最常被忽略的一点:config('app.fallback_locale') 在 API 场景几乎没用——它只影响 trans() 找不到 key 时的兜底行为,但不会帮你自动 fallback 到相近语言(比如用户传 zh_TW 而你只有 zh_CN),这事得自己写逻辑处理。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











