这个答案的灵感来自@FR6,他的答案很旧,并没有涵盖所有问题,所以我做了另一个实现。
我用在 laravel 8.0 中测试的中间件和路由分组处理了这个问题
在你的路由文件web.php 中分组所有需要本地化参数的路由
Route::group([
'prefix' => '{locale}',
'middleware' => 'setLocale'
], function() {
// put your routes here
Route::get('/welcome', function(){
return "Hello";
});
});
// add this so when you call route('...') you don't get the error "parameter 'locale' is not set"
// this is required because all laravel's default auth routes won't add the 'locale' parameter
\Illuminate\Support\Facades\URL::defaults(['locale' => app('locale-for-client')]);
// redirect the home page route to a specific locale
Route::get('/', function () {
return redirect(app('locale-for-client'));
});
创建中间件SetLocalephp artisan make:middleware SetLocale
在app\Middleware\SetLocale.php中,如果在给定的 url 上找不到语言环境,我们将重定向到正确的路由
public function handle(Request $request, Closure $next)
{
$url_lang = $request->segment(1);
if($url_lang !== 'api') {
if (!in_array($url_lang, config('app.locales'), true)) {
return redirect(app('locale-for-client') . '/' . request()->path());
}
app()->setLocale($url_lang);
}
return $next($request);
}
在app\Http\Kernel.php中注册中间件
protected $routeMiddleware = [
...
'setLocale' => \App\Http\Middleware\SetLocale::class,
];
在AppServiceProvider中,我们将定义回退语言。在我的实现中,我使用客户端 cookie 和浏览器定义的语言环境来获取客户端语言环境。
public function register()
{
$this->app->singleton('locale-for-client', function(){
$seg = request()->segment(1);
if(in_array($seg, config('app.locales'), true))
{
// if the current url already contains a locale return it
return $seg;
}
if(!empty(request()->cookie('locale')))
{
// if the user's 'locale' cookie is set we want to use it
$locale = request()->cookie('locale');
}else{
// most browsers now will send the user's preferred language with the request
// so we just read it
$locale = request()->server('HTTP_ACCEPT_LANGUAGE');
$locale = substr($locale, 0, 2);
}
if(in_array($locale, config('app.locales'), true))
{
return $locale;
}
// if the cookie or the browser's locale is invalid or unknown we fallback
return config('app.fallback_locale');
});
}
接下来想在config\app.php 中设置你的语言环境
'locales' => ['en', 'ar', 'fr'],
'locales_text_display' => ['en' => 'English', 'ar' => 'العربية', 'fr' => 'Français'],
'fallback_locale' => 'en',
可选的
由于您已经设置了应用程序区域设置,现在您可能希望让客户根据需要更改他们的区域设置。
- 创建一个控制器
php artisan make:controller AppLocaleController
- 在控制器 AppLocaleController中创建方法更新
public function update()
{
if(in_array(request('locale'), config('app.locales'), true))
{
// using cookie('locale', request('locale')) will encrypt the cookie
// manually set the cookie
header("Set-Cookie:locale=".request('locale').";Max-Age=300000;path=/");
return redirect(url('/'));
}
abort(400);
}
- 注册控制器路由
Route::post('/api/setLocale', [\App\Http\Controllers\AppLanguageController::class, 'update'])
->name('locale.update');