laravel多语言生效的关键是目录结构、locale设置时机和键名占位符三者严丝合缝:resources/lang/zh_cn/下文件路径、键名、:key占位符须完全匹配,app::setlocale()须在视图渲染前调用,carbon等组件需手动绑定locale。

直接说结论:Laravel 多语言不是“配不配得上”,而是“目录结构对不对、locale 设置时机对不对、键名和占位符写没写错”。配错了,__('welcome') 就静默返回 welcome;配对了,连 JSON 文件和复数规则都开箱即用。
resources/lang 目录结构必须严格匹配 locale 值
这是 80% 翻译不生效的根源。Laravel 不识别 zh-CN、zh 或 cn,只认 zh_CN 这种下划线分隔的 IETF 语言标签。
-
resources/lang/zh_CN/messages.php存在,且内容为return ['welcome' => '欢迎']; -
config/app.php中'locale' => 'zh_CN'(仅作初始值,别靠它切语言) - 若用 JSON 格式,路径是
resources/lang/zh_CN/messages.json,内容为{"welcome": "欢迎"} - 子目录名大小写敏感:
zh_cn≠zh_CN,后者才被加载
动态切换语言必须在视图渲染前调用 App::setLocale()
硬写死 config/app.php 的 locale 会导致全站锁死一种语言,无法切换。真正起作用的是运行时的 App::currentLocale()。
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- 在中间件中尽早设置:
App::setLocale(session('locale', config('app.locale'))) - 确保该中间件注册在
StartSession之后,否则读不到 session - 不要在控制器方法里反复调用
App::setLocale(),尤其别在循环或事件监听中 - Artisan 命令或队列任务里没有 session,
App::currentLocale()永远等于config('app.locale'),需显式传参或重设
翻译函数和占位符必须按 Laravel 规则写
__() 和 trans() 底层一致,但参数格式错一个字符就白写。
- 语言文件中必须用
:key占位符,例如'hello' => '你好,:name';{name}或$name完全不替换 - 调用时键名要完全对应:
__('auth.throttle', ['seconds' => 60])要求语言文件里有':seconds' -
@lang('welcome')不走 locale 切换逻辑,统一用{{ __('welcome') }} - 复数规则必须用
trans_choice(),且语言文件中定义形如'comment' => '没有评论|有一条评论|[2,*]有 :count 条评论'
日期、验证等组件不会自动响应 locale 切换
Laravel 的核心组件(如 Carbon、Validator)默认不读取 App::getLocale(),需要手动桥接。
- Carbon 时间显示(如
$post->created_at->diffForHumans())需提前调用Carbon::setLocale(app()->getLocale()),建议放在AppServiceProvider::boot()里 - 验证错误消息依赖
resources/lang/{locale}/validation.php,但自定义 Rule(如Rule::unique())不会自动翻译,需显式用__('validation.unique') - 数据库字段名翻译(如
__('attributes.name'))必须在validation.php的'attributes'数组里明确定义,否则__('validation.required', ['attribute' => 'name'])仍显示name
最易被忽略的点:语言文件路径、键名、占位符三者必须严丝合缝;中间件里 App::setLocale() 必须早于任何视图渲染或验证执行;Carbon 和 Validator 这类“外围”组件需要单独绑定 locale,它们不会跟着 App::getLocale() 自动变。










