Я пытаюсь реализовать простую многоязычную маршрутизацию на основе локали в Laravel 5.6.28, но застрял с перенаправлением после смены языка.
Я хотел бы немедленно перенаправить пользователей на правильный маршрут на основе измененного языкового стандарта всякий раз, когда они меняют его из формы, выбранной на странице.
Я также сделал два класса промежуточного программного обеспечения:
1. SetLocale - для установки языкового стандарта, если он не установлен с помощью HTTP_ACCEPT_LANGUAGE или с учетом первого сегмента запроса (точно, языковой стандарт) .
2. LocaleRedirect - для сравнения локалей пользователя и запроса и перенаправления, если они не совпадают.
Например, если маршрут был '/ ru / блог / stackoverflow'
После смены локали он должен быть '/ гр / блог / stackoverflow'
Но перенаправления не происходит. Что я сделал не так?
Большое спасибо.
Locales:
'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');
});
LanguageController:
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);
}
}
@Azeame Да, это правильно.






Я придумал обходной путь, промежуточное ПО 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();
}
}
Я решил, что отредактировал ответ @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));
}
Вы сопоставили
setlocaleиlocale-redirectс правильными классами вApp\Http\Kernelв разделе$routeMiddleware?