Laravel 8 多语言 JSON 本地化失效的正确实现方案

Laravel 8 多语言 JSON 本地化失效的正确实现方案

laravel 8 中使用 `resources/lang/*.json` 进行多语言切换时,仅调用 `app::setlocale()` 不足以持久生效;必须将语言偏好持久化至 session(或数据库),并避免在运行时执行 artisan 命令。

在 Laravel 8+ 中,JSON 语言文件(如 en.json、ar.json)是官方支持的本地化方式,但其生效依赖于请求生命周期内正确的 locale 设置时机与作用域。你当前代码中在 switchLang 方法和中间件里频繁调用 config:clear、config:cache 和 cache:clear 是严重错误——这些 Artisan 命令仅应在部署阶段手动执行,绝不可在 HTTP 请求中动态触发,它们会清空整个配置缓存、影响并发请求,甚至导致应用异常。

✅ 正确做法是:设置 locale + 持久化用户语言偏好。推荐优先使用 Session 存储,简洁可靠:

1. 更新语言切换逻辑(Controller)

// app/Http/Controllers/HomeController.php
public function switchLang($lang)
{
    // 验证语言代码合法性(防止路由注入)
    $supportedLocales = ['en', 'ar']; // 可从 config/app.php 的 'locales' 扩展
    if (!in_array($lang, $supportedLocales)) {
        abort(400, 'Unsupported language');
    }

    // 写入 Session 并设置当前请求 locale
    session()->put('locale', $lang);
    app()->setLocale($lang);

    return redirect()->back();
}

2. 创建并注册语言中间件(推荐方式)

// app/Http/Middleware/SetLocale.php

在 app/Http/Kernel.php 中注册为全局中间件(置于 $middlewareGroups['web'] 中靠前位置,确保在视图渲染前生效):

'web' => [
    /App/Http/Middleware/EncryptCookies::class,
    /Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse::class,
    /Illuminate/Session/Middleware/StartSession::class,
    /Illuminate/View/Middleware/ShareErrorsFromSession::class,
    /App/Http/Middleware/SetLocale::class, // ← 放在这里
    // ... 其他中间件
],

3. 视图中使用 JSON 翻译(无需前缀)

确保 resources/lang/en.json 和 ar.json 结构为扁平键值对:

钛投标

钛投标

钛投标 | 全年免费 | 不限字数 | AI标书智写工具

下载

// resources/lang/en.json
{
  "Welcome": "Welcome",
  "Logout": "Logout"
}
// resources/lang/ar.json
{
  "Welcome": "مرحبا",
  "Logout": "تسجيل الخروج"
}

在 Blade 中直接使用:

{{ __('Welcome') }}

{{ __('Switch to Arabic') }}

⚠️ 注意事项

  • 禁止在控制器/中间件中调用 Artisan::call():它会 fork 进程、清空缓存,破坏无状态请求模型,且极慢。
  • Session 必须启用:确认 config/session.php 中驱动正常(如 file 或 redis),且 StartSession 中间件已加载。
  • ? 安全增强:对 $lang 参数做白名单校验(如示例所示),防止任意 locale 注入。
  • ? 进阶建议:若需用户级语言偏好(登录用户永久保存),可将 locale 字段添加至 users 表,并在中间件中优先读取 Auth::user()?->locale。

通过以上改造,JSON 本地化即可稳定工作——每次请求自动加载对应语言包,无需重启服务或手动清缓存。

https://www.php.cn/faq/2011076.html

发表回复

Your email address will not be published. Required fields are marked *