php Laravel 更改语言环境不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41265880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel change locale not working
提问by Vahn Marty
I am using a dropdown lists for the languages, consisting of english and dutch.
我正在使用语言的下拉列表,包括英语和荷兰语。
<form class="" action="{{url('/locale')}}" method="post">
Locale:
<select class="" name="locale" onchange="this.form.submit()">
<option value="en" >English</option>
<option value="du" >Dutch</option>
</select>
</form>
Then this is my routes.php,
然后这是我的routes.php,
Route::post('/locale', function(){
\App::setLocale(Request::Input('locale'));
return redirect()->back();
});
And it is not working.
它不工作。
In my project, the path is like this
在我的项目中,路径是这样的
resources/
/du
navigation.php
/en
/navigation.php
From the Dutch(du) 'navigation.php'
来自荷兰语(du)'navigation.php'
<?php
return [
"home" => 'Home-test-dutch',
];
and for the English(en) 'navigation.php'
和英语(en)'navigation.php'
<?php
return [
"home" => 'Home',
];
采纳答案by Vahn Marty
I solved my problem from this article https://mydnic.be/post/laravel-5-and-his-fcking-non-persistent-app-setlocale
我从这篇文章https://mydnic.be/post/laravel-5-and-his-fcking-non-persistent-app-setlocale解决了我的问题
Thanks to the people who contributed the word 'non persistent'
感谢贡献“非坚持”一词的人
回答by Froxz
App::setLocale()
is not persistent, it set locale only for current request(runtime). What you can do:
App::setLocale()
不是持久的,它只为当前请求(运行时)设置语言环境。你可以做什么:
Route::post('/locale', function(){
session(['my_locale' => Request::Input('locale')]);
return redirect()->back();
});
This will set session key
for current user
After we will need a Middleware
to detect locale
这将为session key
当前用户设置之后我们需要一个Middleware
来检测语言环境
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
class Language {
public function __construct(Application $app, Request $request) {
$this->app = $app;
$this->request = $request;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$this->app->setLocale(session('my_locale', config('app.locale')));
return $next($request);
}
}
This will get current session and if is empty will fallback to default locale, which is set in your app config.
这将获取当前会话,如果为空将回退到默认语言环境,这是在您的应用程序配置中设置的。
In app\Http\Kernel.php
add previously created Language
middleware:
在app\Http\Kernel.php
先前创建的Language
中间件:
protected $middleware = [
\App\Http\Middleware\Language::class,
];
As global middlware or just for web (based on your needs). I hope this helps, and gives an idea on how things are working.
作为全球中间件或仅用于网络(根据您的需要)。我希望这会有所帮助,并提供有关事情如何运作的想法。
Scenario №2Create an array
with all available locales on your app inside app config
场景 №2array
在您的应用程序中
创建一个包含所有可用区域设置的文件app config
'available_locale' => ['fr', 'gr', 'ja'],
Inside the Middleware we will check the URL first segment en fr gr cy
if this segment is in available_locale
, set language
在中间件内部,我们将检查 URL 第一段,en fr gr cy
如果该段在available_locale
, 设置语言
public function handle($request, Closure $next)
{
if(in_array($request->segment(1), config('app.available_locale'))){
$this->app->setLocale($request->segment(1));
}else{
$this->app->setLocale(config('app.locale'));
}
return $next($request);
}
You will need to modify app\Providers\RouteServiceProvider
for setting prefix to all your routes. so you can access them domain.com
or domain.com/fr/
with French language
Find: mapWebRoutes
And add this to it: (before add use Illuminate\Http\Request;
)
您将需要修改app\Providers\RouteServiceProvider
以设置所有路由的前缀。因此您可以访问它们domain.com
或domain.com/fr/
使用French language
Find:mapWebRoutes
并将其添加到其中:(添加之前use Illuminate\Http\Request;
)
public function map(Request $request)
{
$this->mapApiRoutes();
$this->mapWebRoutes($request);
}
protected function mapWebRoutes(Request $request)
{
if(in_array($request->segment(1), config('app.available_locale'))){
$locale = $request->segment(1);
}else{
$locale = null;
}
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'prefix' => $locale
], function ($router) {
require base_path('routes/web.php');
});
}
This will prefix all your routes with country letter like 'fr gr cy' except en for non-duplicate content, so is better to not add into available_locales_array
这将为您的所有路线加上国家字母,如“fr gr cy”,除了 en 用于非重复内容,所以最好不要添加到 available_locales_array
回答by rap-2-h
App::setLocale()
is not persistent.
I had a similar problem before so I created a middleware:
App::setLocale()
不持久。我之前遇到过类似的问题,所以我创建了一个中间件:
<?php
namespace App\Http\Middleware;
use Closure;
class SetLocale
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (strpos($request->getHttpHost(), 'fr.') === 0) {
\App::setLocale('fr');
} else {
\App::setLocale('en');
}
return $next($request);
}
}
And I registered this middleware in app\Http\Kernel
:
我在app\Http\Kernel
以下位置注册了这个中间件:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\SetLocale::class,
// ...
]
];
This script works for two domains: http://example.org(en) and http://fr.example.org(fr). As a middleware, it's called on every request, so the locale is always set as the right locale according to the url.
此脚本适用于两个域:http: //example.org(en) 和http://fr.example.org(fr)。作为一个中间件,它在每个请求上都会被调用,所以语言环境总是根据 url 设置为正确的语言环境。
My routes looked like:
我的路线看起来像:
Route::group(['domain' => 'fr.' . config('app.root-domain')], function () {
Route::get('a-propos', 'HomeController@about');
// ...
}
Route::group(['domain' => config('app.root-domain')], function () {
Route::get('about', 'HomeController@about');
// ...
}
So it responds with the correct locale to:
所以它以正确的语言环境响应:
And I use the same controller and same view, just 2 different routes + a global middleware.
我使用相同的控制器和相同的视图,只有 2 个不同的路由 + 一个全局中间件。
Hope it will help, not sure it's the best solution BTW. This solution works without sessio, it matches with domain and/or routes. It has some advantages over session-based solutions:
希望它会有所帮助,但不确定这是最好的解决方案。此解决方案无需 sessio,它与域和/或路由匹配。与基于会话的解决方案相比,它具有一些优势:
- No possible bugs due to session usage ("magic" language switch)
- You can rewrite your routes. A french user may want to see "/mon-panier" and english user "/my-cart" in their url.
- Better indexing in google (SEO), because you can have a real index by country with relevant content.
- I use it in production!
- 由于会话使用(“魔术”语言切换),没有可能的错误
- 你可以重写你的路线。法国用户可能希望在其 URL 中看到“/mon-panier”和英语用户“/my-cart”。
- 在谷歌 (SEO) 中建立更好的索引,因为您可以按国家/地区获得包含相关内容的真实索引。
- 我在生产中使用它!
It may have it's cons too.
它也可能有它的缺点。
回答by Afraz Ahmad
When user selects language from dropdown, call below route to save language in session
当用户从下拉列表中选择语言时,调用下面的路由以在会话中保存语言
Using Vue.js
使用 Vue.js
LocalizationComponent.vuechange language
LocalizationComponent.vue更改语言
<template>
<ul>
<li @click="changeLanguage('en')">
<a href="javascript:void(0);">
<img src="/images/flag-1.png" alt="image description">
<span>ENG</span>
</a>
</li>
<li @click="changeLanguage('vn')">
<a href="javascript:void(0);">
<img src="/images/flag-2.png" alt="image description">
<span>Vi?t</span>
</a>
</li>
</ul>
<script>
export default{
data(){
return {
selected_language:'en',
}
},
methods:{
changeLanguage(language){
this.axios.post('/change-locale',{language:language}).then(
(response) => {window.location.reload();
}).catch((error) => {
console.log(error.response.data.errors)
});
localStorage.setItem('selected_language',language);
}
}
}
</script>
routes/web.php
路线/ web.php
Route::post('/change-locale', 'HomeController@changeLocale');
//save locale to session
//保存区域设置到会话
public function changeLocale(Request $request)
{
$language = $request->language ?? 'en';
session(['selected_language' =>$language]);
}
//create middleware to set locale
//创建中间件来设置语言环境
class Localization
{
public function handle($request, Closure $next)
{
App::setLocale(session()->get('selected_language') ?? 'en');
return $next($request);
}
}
In app/Http/Kernel.php
在 app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
...other middelwares
Localization::class, //add your localization middleware here
],
//...
];
Done...
完毕...
回答by martindilling
setLocale
will only change the language for the rest of the request from that point on.
setLocale
从那时起,只会更改其余请求的语言。
So to persist it, you could look into setting the selected language in a session (https://laravel.com/docs/session). Then you can create a middeware (https://laravel.com/docs/middleware) where you can check if a language is set in the session and then apply it for the request :)
因此,要坚持下去,您可以考虑在会话中设置所选语言(https://laravel.com/docs/session)。然后您可以创建一个中间件 ( https://laravel.com/docs/middleware),您可以在其中检查会话中是否设置了语言,然后将其应用于请求:)