
升级 laravel 8 到 9 后,若将 `resources/lang` 移至项目根目录 `lang/` 但翻译未生效,通常是因为旧目录未彻底删除,导致 laravel 优先加载残留的 `resources/lang`,从而忽略新路径。
Laravel 9 确实将语言文件默认路径从 resources/lang 迁移至项目根目录下的 lang/(即 base_path('lang')),这是框架内部语言加载器(TranslationLoader)的硬编码查找逻辑变更所致。然而,该迁移并非强制覆盖式切换,而是采用“多路径回退查找”机制:Laravel 会按顺序检查以下路径,并使用第一个存在且非空的语言目录:
- resources/lang(向后兼容保留)
- lang(Laravel 9 新默认路径)
这意味着:只要 resources/lang 目录仍存在于项目中(即使为空或仅含 .gitkeep),Laravel 就会停止继续查找,直接使用该路径——而你的旧目录很可能已无有效语言文件,导致 Lang::get() 返回原始键名(如 "messages.welcome"),而非翻译值。
✅ 正确迁移步骤如下:
-
彻底删除旧目录:
rm -rf resources/lang
⚠️ 注意:不要仅重命名或移动,必须确保该路径完全不存在。可通过 ls resources/ 验证。
-
确保新目录结构正确:
lang/ └── pt-BR/ └── messages.php # 返回 ['welcome' => 'Welcome to the app!'] -
清空配置与语言缓存(关键!):
php artisan config:clear php artisan lang:clear # Laravel 9.19+ 支持;旧版可手动删除 storage/framework/cache/data/*lang* php artisan view:clear
-
验证配置无误:
// config/app.php 'locale' => 'pt-BR',
-
测试调用(推荐使用辅助函数提升可读性):
// Controller 或任意位置 return response()->json([ 'message' => __('messages.welcome'), // 推荐:比 Lang::get() 更简洁 // 或 // 'message' => \Lang::get('messages.welcome') ]);
? 补充说明:
- 新建 Laravel 9 项目默认不包含 resources/lang,因此天然使用 lang/,这也是为何“全新项目能正常工作”的原因;
- composer.json 依赖一致 ≠ 配置状态一致,迁移需关注文件系统状态与缓存状态;
- 若因历史原因需保留 resources/lang(如多环境差异化部署),可通过自定义 TranslationServiceProvider 覆盖加载路径,但违背升级初衷,不建议。
完成上述操作后,__('messages.welcome') 将正确返回 'Welcome to the app!',语言系统即可按 Laravel 9 规范稳定运行。










