Перенаправление Laravel на маршрут при изменении локали

Я пытаюсь реализовать простую многоязычную маршрутизацию на основе локали в 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);
    }
}

Вы сопоставили setlocale и locale-redirect с правильными классами в App\Http\Kernel в разделе $routeMiddleware?

Azeame 21.07.2018 18:26

@Azeame Да, это правильно.

Khasky 21.07.2018 21:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
2
5 434
2

Ответы 2

Я придумал обходной путь, промежуточное ПО 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));

    }

Другие вопросы по теме