Laravel重定向到区域更改路由

时间:2018-07-21 15:43:34

标签: php laravel localization locale middleware

我正在尝试在Laravel 5.6.28中基于语言环境实现简单的多语言路由,但是在更改语言后一直停留在重定向上。

无论何时从页面上的表单选择中更改用户,我都希望立即根据更改的语言环境将用户重定向到正确的路由。

我还制作了两个中间件类:
1. SetLocale -用于设置语言环境(如果未使用HTTP_ACCEPT_LANGUAGE设置或未考虑需求的第一部分(完全是语言环境)。
2. LocaleRedirect -用于比较用户和请求区域设置,如果不匹配则重定向。

例如,如果路由为'/ en / blog / stackoverflow'
更改语言环境后,应为'/ gr / blog / stackoverflow'
但是不会发生重定向。我做错了什么?
非常感谢。

语言环境

'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);
    }
}

2 个答案:

答案 0 :(得分: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();
    }
}

答案 1 :(得分:0)

我通过编辑@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));

    }