如何检测Laravel 5中的语言偏好

Nan*_*oel 7 locale laravel-5

我想通过获取浏览器推荐的语言来检测我的客户端语言.

例如,如果您在日本打开浏览器,它将为我提供当前用户打开的国家代码或国家/地区名称,如"en-jp"或"japan".

我尝试这个代码,但它似乎显示我之前选择的语言,默认情况下它是英语.

我设置了一个中间件,我需要排除api部分,因为我有一些路由器ping这个地址,路由器浏览器没有语言信息阻塞系统.

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 */
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

edc*_*dcs 13

要从标头中简单地获取区域设置,您可以http-accept-language从请求中获取值.这可以通过外观访问,也可以在中间件中使用请求变量:

Request::server('HTTP_ACCEPT_LANGUAGE')

// OR

$request->server('HTTP_ACCEPT_LANGUAGE');
Run Code Online (Sandbox Code Playgroud)

这将返回一个如下所示的字符串:en-GB,en;q=0.8.然后你可以解析它(也许使用explode()?)并从那里获取语言.

然而,这种事情有时会变得复杂.如果你需要做一些更高级的事情,有一个包可以为你做所有这些:

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


小智 12

或者你可以使用 Illuminate\Http\Request::getPreferredLanguage

像这样,在中间件中:

<?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);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • `getPreferredLanguage` 的使用是完美的,因为它是内置的。它是“Symphony”框架的一部分,并且是自动提供的。 (2认同)
  • @TimVisée 谢谢 Tim,我很好奇这是在哪里记录的,但在 Laravel 中找不到它。请参阅交响乐:https://github.com/symfony/symfony/blob/47da6640f8f88d56968813247806148283106b82/src/Symfony/Component/HttpFoundation/Request.php#L1644 (2认同)

Ant*_*ida 6

我只是为此制作了一个中间件,它可能很有用。

首先,您$availableLangs在应用程序中设置了可用语言的数组,您可能会使用config\app.php而不是像我一样在中间件中初始化数组。

如果请求语言数据中提供了第一种语言,它将设置区域设置,否则,它将搜索下一个,依此类推。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 它有效,但是问题是您使用$ availableLangs强制使用语言环境顺序,而不是使用$ userLangs定义的顺序。遍历$ userLangs并检查是否在$ availableLangs中定义。我们应该始终遵循浏览器首选的语言选择。 (4认同)