Laravel 在区域设置更改时重定向到路由
Posted
技术标签:
【中文标题】Laravel 在区域设置更改时重定向到路由【英文标题】:Laravel redirect to route on locale change 【发布时间】:2018-12-29 15:48:40 【问题描述】:我正在尝试在 Laravel 5.6.28 中基于语言环境实现简单的多语言路由,但在语言更改后一直坚持重定向。
每当用户从页面上的表单选择中更改时,我想根据更改的区域设置立即将用户重定向到正确的路线。
我还做了两个中间件类: 1. SetLocale - 如果未使用 HTTP_ACCEPT_LANGUAGE 设置或考虑 reqeust 的第一段(准确的区域设置),则用于设置区域设置。 2. LocaleRedirect - 用于比较用户和请求区域设置,如果它们不匹配则重定向。
例如,如果路由是 '/en/blog/***' 更改语言环境后,它应该是 '/gr/blog/***' 但不会发生重定向。我做错了什么? 非常感谢。
区域设置:
'locales' => [
'en' => 'English',
'es' => 'Spanish',
'gr' => 'Greek'
]
页面:
!! Form::open(['route' => 'language.change']) !!
Language:
!! Form::select('lang', config('translatable.locales'), app()->getLocale(), ['id' => 'language-select']); !!
!! Form::close() !!
<script>
$(function ()
$('#language-select').on('change', function ()
$(this).closest('form').submit();
);
);
</script>
路线:
Route::post('language/change', 'LanguageController@postChangeLanguage')->name('language.change');
Route::group([
'prefix' => 'locale',
'middleware' => ['setlocale', 'locale-redirect'],
'where' => ['locale' => implode('|', array_keys(config('translatable.locales')))]
], function ()
Route::get('page', function ($locale)
return view(Helper::getLocaleView($locale, 'page'));
);
Route::get('home', function ($locale)
return view(Helper::getLocaleView($locale, 'home'));
);
);
Route::get('/', function ()
return redirect()->to('en/home');
);
语言控制器:
class LanguageController extends Controller
public function postChangeLanguage(Request $request)
$changeLang = $request->input('lang');
$userLang = app()->getLocale();
if ($userLang !== $changeLang && array_key_exists($changeLang, config('translatable.locales')))
session(['locale' => $changeLang]);
app()->setLocale($changeLang);
return redirect()->back();
SetLocale 中间件:
class SetLocale
public function handle($request, Closure $next)
if ($request->method() === 'GET')
$requestLocale = $request->segment(1);
if (array_key_exists($requestLocale, config('translatable.locales')))
session(['locale' => $requestLocale]);
else if (!session()->has('locale'))
$browserLanguage = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if (array_key_exists($browserLanguage, config('translatable.locales')))
session(['locale' => $browserLanguage]);
else
session(['locale' => config('translatable.fallback_locale')]);
app()->setLocale(session('locale'));
return $next($request);
LocaleRedirect 中间件:
class LocaleRedirect
public function handle($request, Closure $next)
$requestLocale = $request->segment(1);
$userLocale = session('locale');
if ($requestLocale !== $userLocale)
$segments = $request->segments();
array_shift($segments);
array_unshift($segments, $userLocale);
return redirect()->to(implode('/', $segments));
return $next($request);
【问题讨论】:
您是否将setlocale
和locale-redirect
映射到App\Http\Kernel
下$routeMiddleware
下的正确类?
@Azeame 是的,映射正确。
【参考方案1】:
我想出了解决方法,不再需要 LocaleRedirect 中间件。
class LanguageController extends Controller
public function postChangeLanguage(Request $request)
$changeLang = $request->input('lang');
$userLang = session('locale');
if ($userLang !== $changeLang && array_key_exists($changeLang, config('translatable.locales')))
session(['locale' => $changeLang]);
app()->setLocale($changeLang);
$segments = str_replace(url('/'), '', url()->previous());
$segments = array_filter(explode('/', $segments));
array_shift($segments);
array_unshift($segments, $changeLang);
return redirect()->to(implode('/', $segments));
return redirect()->back();
【讨论】:
【参考方案2】:我通过编辑@khasky 的答案解决了这个问题
public function changeLanguage(Request $request)
$changeLang = $request->lang;
$userLang = session('locale');
session(['locale' => $changeLang]);
app()->setLocale($changeLang);
$segments = str_replace(url('/'), '', url()->previous());
$segments = array_filter(explode('/', $segments));
array_shift($segments);
array_unshift($segments, $changeLang);
return redirect()->to(implode('/', $segments));
【讨论】:
以上是关于Laravel 在区域设置更改时重定向到路由的主要内容,如果未能解决你的问题,请参考以下文章