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

Laravel 5.6路由Locale设置异常:始终默认'en'问题求助

这个问题我之前也碰到过!你原来的写法有个关键误区——App::setLocale()是在路由注册的时候执行的,不是用户请求到来的时候。当你的Laravel应用启动加载路由文件时,两个路由组里的setLocale会依次跑一遍,最后执行的是en那个,所以不管你访问fr/home还是en/home,Locale都会被定格成en,这就是为啥始终返回'en'的原因。

给你推荐最优雅的解决方案:用中间件来动态设置Locale,因为中间件是在请求处理流程中触发的,能精准对应当前请求的前缀。

步骤1:创建Locale中间件

先运行Artisan命令生成中间件:

php artisan make:middleware SetLocale

然后打开app/Http/Middleware/SetLocale.php,把逻辑改成这样:

<?php

namespace App\Http\Middleware;

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

class SetLocale
{
    public function handle($request, Closure $next)
    {
        // 从路由前缀获取locale值
        if ($locale = $request->route('locale')) {
            // 先验证是否是我们允许的语言,避免非法值
            if (in_array($locale, ['en', 'fr'])) {
                App::setLocale($locale);
            }
        }

        return $next($request);
    }
}

步骤2:注册中间件

打开app/Http/Kernel.php,在$routeMiddleware数组里添加这个中间件的别名:

protected $routeMiddleware = [
    // 其他中间件...
    'setlocale' => \App\Http\Middleware\SetLocale::class,
];

步骤3:重构路由定义

不用再写重复的路由组了,用参数化前缀+中间件的方式,简洁又灵活:

Route::group(['prefix' => '{locale}', 'middleware' => 'setlocale'], function () {
    Route::get('home', 'HomeController@index');
    // 所有需要多语言支持的路由都可以放在这个组里
});

如果你实在想分开写两个前缀(比如有特殊需求),也可以给每个组单独加中间件:

Route::group(['prefix' => 'fr', 'middleware' => 'setlocale'], function () {
    Route::get('home', 'HomeController@index');
});
Route::group(['prefix' => 'en', 'middleware' => 'setlocale'], function () {
    Route::get('home', 'HomeController@index');
});

不过参数化的方式显然更省心,不用重复写相同的路由逻辑。

测试验证

现在访问fr/home,在HomeController@index里调用App::getLocale(),应该就能返回'fr'了;访问en/home则返回'en',完美解决问题!

另外提个小建议:最好把允许的语言列表放到配置文件里(比如config/app.php新增locales数组),这样后续添加语言时不用改中间件代码,更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:15:43