How to detect language preference in Laravel 5

馋奶兔 提交于 2019-12-18 16:29:07

问题


I want to detect my client language by getting the browser recommended language.

For Example, if you open the browser in Japan it will give me country code or country name current user opened like "en-jp" or "japan".

I try this code but it seems to display the language that I previously selected and by default it's English.

I set a Middleware and I need to exclude the api part because I have some routers pinging this address and router browser does not have language information which brick the system.

class BeforeMiddleware
{

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request $request
 * @param  \Closure $next
 * @return mixed
 */

protected $except_urls = [
    'api/*'
];

public function handle($request, Closure $next)
{
    $langArr = array("en", "fr");
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
        $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
    } else {
        $languages[0] = "en";
    }
    if (Session::has('locale')) {
        App::setLocale(Session::get('locale'));
    } else {
        if (in_array($languages[0], $langArr))
            App::setLocale($languages[0]);
    }
    return $next($request);
}


} /* end class */

Thank you for you help.


回答1:


To simply get the locale from the header, you can grab the http-accept-language value from the request. This is accessible via a facade or you can use the request variable in your middleware:

Request::server('HTTP_ACCEPT_LANGUAGE')

// OR

$request->server('HTTP_ACCEPT_LANGUAGE');

This returns a string which looks like this: en-GB,en;q=0.8. You can then parse it (perhaps using explode()?) and grab the language from there.

However, this sort of thing can sometimes get complicated. If you need to do something more advanced, there's a package which can do all of this for you:

https://github.com/mcamara/laravel-localization




回答2:


Or you can use Illuminate\Http\Request::getPreferredLanguage

Like this, in middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Request;

class Locale {

  const SESSION_KEY = 'locale';
  const LOCALES = ['en', 'cs'];

  public function handle(Request $request, Closure $next) {
    /** @var Session $session */
    $session = $request->getSession();

    if (!$session->has(self::SESSION_KEY)) {
      $session->put(self::SESSION_KEY, $request->getPreferredLanguage(self::LOCALES));
    }

    if ($request->has('lang')) {
      $lang = $request->get('lang');
      if (in_array($lang, self::LOCALES)) {
        $session->put(self::SESSION_KEY, $lang);
      }
    }

    app()->setLocale($session->get(self::SESSION_KEY));

    return $next($request);
  }
}



回答3:


I just made a Middleware for this, it may be useful.

First you set $availableLangs the array of the available languages in your app, you may use config\app.php instead of initializing the array in the middleware as I did.

If the first language is available in the request language data, it sets the locale, if not, it will search the next one, and so on.

class GetRequestLanguage
{

    public function handle($request, Closure $next)
    {
        if (Session::has('locale')) {
            App::setLocale(Session::get('locale'));
        } else {
            $availableLangs = ['pt', 'en'];
            $userLangs = preg_split('/,|;/', $request->server('HTTP_ACCEPT_LANGUAGE'));

            foreach ($availableLangs as $lang) {
                if(in_array($lang, $userLangs)) {
                    App::setLocale($lang);
                    Session::push('locale', $lang);
                    break;
                }
            }
        }

        return $next($request);
    }
}



回答4:


In a middleware do:

$acceptableLocales = config('app.available_locales');
            $userLocales = $request->getLanguages();
            if(!empty($userLocales)) {
                    foreach ($userLocales as $lang) {
                            $langToSearch = str_replace('_','-',$lang);
                            if(in_array($langToSearch, $acceptableLocales)) {
                                   app('translator')->setLocale($langToSearch);
                                    break;
                            }
                    }
            }
            return $next($request);

If you want to return the language in the response to the client, create another middleware and do:

/** @var Response $response */
            $response = $next($request);
            $response->header('Content-Language', app('translator')->getLocale());
            return $response;



回答5:


I use a middleware too, but a lit bit smaller.

<?php

namespace Transfer\Http\Middleware;

use Closure;

class SetLanguage
{
    public function handle($request, Closure $next)
    {
        $locale = $request->getLocale();

        if ($request->session()->has('locale')) {
            $locale = $request->session()->get('locale');
        }

        config(['app.locale' => $locale]);

        return $next($request);
    }
}


来源:https://stackoverflow.com/questions/36986236/how-to-detect-language-preference-in-laravel-5

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!