Laravel的本地化通过会话进行,但未在全局生效(会话中的语言环境已更改,但app()->getLocale() 仍保持不变)

后端开发 2026-07-11

我正在尝试在一个Laravel 12项目中实现本地化(英语/日语),并使用基于会话的语言切换。

我有一个切换语言的路由:

Route::get('/lang/{locale}', function ($locale) {
    if (!in_array($locale, ['en', 'ja'])) {
        abort(400);
    }

    session()->put('locale', $locale);

    return redirect()->back();
})->name('lang.switch');

我创建了一个中间件:

namespace App\Http\Middleware;

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

class SetLocale
{
    public function handle($request, Closure $next)
    {
        $locale = session('locale', 'en');

        App::setLocale($locale);

        return $next($request);
    }
}

并在 web 中的 Kernel.php 组内注册它:

protected $middlewareGroups = [
    'web' => [
        \Illuminate\Cookie\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,

        \App\Http\Middleware\SetLocale::class,

        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

在我的Blade视图 (dashboard.blade.php) 中,我显示:

SESSION: {{ session('locale') }} <br>
APP: {{ app()->getLocale() }}

<h1>{{ __('messages.dashboard') }}</h1>
<h2>{{ __('messages.system_overview') }}</h2>

翻译文件:

resources/lang/en/messages.php

return [
    'dashboard' => 'Dashboard',
    'system_overview' => 'System Overview',
];

resources/lang/ja/messages.php

return [
    'dashboard' => 'ダッシュボード',
    'system_overview' => 'システム概要',
];

问题

  • session('locale') 正确地变化(en / ja
  • 导航菜单翻译正确
  • 但在仪表板上:

  • app()->getLocale() 仍然是 en

  • 翻译未更新

我尝试了什么

  • 清理缓存:

php artisan optimize:clear php artisan view:clear * 验证中间件已注册 * 验证翻译文件是否正确 * 删除语言文件中的重复键 * 中间件正在正确执行


问题

为什么 session('locale') 能正确更新,但 app()->getLocale() 在Blade视图中没有反映出来?

在Laravel 12是否有关于中间件执行顺序或本地化处理的具体机制,我可能遗漏的?

解决方案

这不是翻译文件的问题。它是请求生命周期/中间件注册的问题。

在Laravel 11/12中,中间件的注册通常在 bootstrap/app.php 中完成,而不是 app/Http/Kernel.php

bootstrap/app.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Symfony\Component\HttpFoundation\Response;

class SetLocale
{
    public function handle(Request $request, Closure $next): Response
    {
        $locale = $request->session()->get('locale', config('app.locale')); # use the Request session directly (Better middleware code)

        if (! in_array($locale, ['en', 'ja'])) {
            $locale = config('app.locale');
        }

        App::setLocale($locale);

        return $next($request);
    }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章