You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8 使用JSON语言包实现本地化功能不生效如何解决

问题核心原因

你的代码不生效是三个低级错误导致的:

  • App::setLocale() 仅对当前单次请求生效,你在切换方法里设置完直接重定向,新请求不会保留之前设置的语言值,等于白设
  • 自定义中间件写法完全错误:既没有从持久化存储里读取用户选择的语言,还错误给handle方法加了无法自动注入的$lang参数
  • 每次请求都执行config:clear/config:cache/cache:clear是完全错误的用法,这些运维类命令只应该在部署时手动执行,请求里调用会严重拖垮性能,也不会帮你持久化语言设置
分步解决方法

第一步:先校验基础配置正确性

  • 确认语言文件路径匹配你的Laravel版本:Laravel 9+默认语言目录是和app同级的lang/文件夹,Laravel 6-8默认是resources/lang/,你放的en.json、ar.json要在对应目录根路径下
  • 确认JSON文件格式合法:不能有多余的尾逗号(最后一个键值对后面不能加逗号),文件编码为UTF-8无BOM格式,示例内容:
// en.json 示例
{
    "Welcome": "Welcome",
    "Login": "Login"
}
  • 提前在config/app.php里定义好支持的语言列表,避免传入非法值:
'available_locales' => ['en', 'ar'],

第二步:修正语言切换路由与控制器逻辑

首先修改路由,增加语言参数合法性校验,web.php代码调整为:

Route::get('lang/{lang}', [HomeController::class,'switchLang'])->name('lang')->whereIn('lang', config('app.available_locales'));

然后修改控制器里的切换方法,删掉所有请求内调用artisan缓存命令的代码,把用户选择的语言存入session(session是跨请求持久化存储的载体):

public function switchLang($lang)
{
    if (!in_array($lang, config('app.available_locales'))) {
        abort(400);
    }
    session(['app_locale' => $lang]);
    return redirect()->back();
}

第三步:编写正确的全局语言中间件

删掉你之前中间件里多余的参数、多余的artisan命令,中间件的作用是每次请求启动时,从session里读取用户之前选好的语言,设置到当前请求中。修改Language.php代码:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class Language
{
    public function handle(Request $request, Closure $next)
    {
        $locale = session('app_locale', config('app.locale'));
        if (in_array($locale, config('app.available_locales'))) {
            App::setLocale($locale);
        }
        return $next($request);
    }
}

然后打开app/Http/Kernel.php,把中间件注册到web中间件组,确保所有走web路由的请求都会经过这个中间件:

protected $middlewareGroups = [
    'web' => [
        // 框架自带的其他中间件保持不动
        \App\Http\Middleware\Language::class,
    ],
];

第四步:常见不生效问题排查

  • 如果你之前跑过路由缓存,在命令行手动执行一次php artisan route:clear清除旧路由缓存即可
  • 翻译调用要符合JSON文件规则:在模板里用{{ __('Welcome') }}直接取JSON中对应键的翻译值,不需要加文件前缀
  • 确认你的业务路由都在web.php里,或者都加载了web中间件组——只有web中间件组会启用session,放在api.php里的路由无法读取session存储的语言值
  • 阿拉伯语这类RTL语言要手动给html标签加dir="rtl"属性,不要因为页面排版问题误以为翻译没生效

内容的提问来源于stack exchange,提问作者HAMZA HUMMAM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.14 16:15:48