Merge pull request #932 from chunhei2008/fix/929

Fix/929 Translator 的 setLocale 会有协程数据混淆的问题
This commit is contained in:
李铭昕 2019-11-13 10:14:39 +08:00 committed by GitHub
commit 28091318ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 11 deletions

View File

@ -16,6 +16,7 @@
- [#904](https://github.com/hyperf/hyperf/pull/904) Fixed the hooked I/O request does not works in the listener that listening `Hyperf\Framework\Event\BeforeMainServerStart` event.
- [#906](https://github.com/hyperf/hyperf/pull/906) Fixed `port` property of URI of `Hyperf\HttpMessage\Server\Request`.
- [#909](https://github.com/hyperf/hyperf/pull/909) Fixed a issue that causes staled parallel execution.
- [#932](https://github.com/hyperf/hyperf/pull/932) Fixed `Translator::setLocale` does not works in coroutine evnironment.
# v1.1.5 - 2019-11-07

View File

@ -36,6 +36,8 @@ return [
## 配置语言环境
### 配置默认语言环境
关于国际化组件的相关配置都是在 `config/autoload/translation.php` 配置文件里设定的,你可以按照实际需要修改它。
```php
@ -52,6 +54,30 @@ return [
];
```
### 配置临时语言环境
```php
<?php
use Hyperf\Di\Annotation\Inject;
use Hyperf\Contract\TranslatorInterface;
class FooController
{
/**
* @Inject
* @var TranslatorInterface
*/
private $translator;
public function index()
{
// 只在当前请求或协程生命周期有效
$this->translator->setLocale('zh_CN');
}
}
```
# 翻译字符串
## 通过 TranslatorInterface 翻译
@ -135,4 +161,4 @@ echo __('messages.welcome', ['name' => 'Hyperf']);
echo trans_choice('messages.apples', 10);
```
当然除了全局函数 `trans_choice()`,您也可以使用 `Hyperf\Contract\TranslatorInterface``transChoice` 方法。
当然除了全局函数 `trans_choice()`,您也可以使用 `Hyperf\Contract\TranslatorInterface``transChoice` 方法。

View File

@ -17,6 +17,7 @@ use Hyperf\Contract\TranslatorInterface;
use Hyperf\Contract\TranslatorLoaderInterface;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Collection;
use Hyperf\Utils\Context;
use Hyperf\Utils\Str;
use Hyperf\Utils\Traits\Macroable;
@ -111,7 +112,7 @@ class Translator implements TranslatorInterface
// was not passed, we will use the default locales which was given to us when
// the translator was instantiated. Then, we can load the lines and return.
$locales = $fallback ? $this->localeArray($locale)
: [$locale ?: $this->locale];
: [$locale ?: $this->locale()];
foreach ($locales as $locale) {
if (! is_null($line = $this->getLine(
@ -138,7 +139,7 @@ class Translator implements TranslatorInterface
*/
public function getFromJson(string $key, array $replace = [], ?string $locale = null)
{
$locale = $locale ?: $this->locale;
$locale = $locale ?: $this->locale();
// For JSON translations, there is only one file per locale, so we will simply load
// that file and then we will be ready to check the array for the key. These are
@ -315,12 +316,22 @@ class Translator implements TranslatorInterface
return $this->getLocale();
}
/**
* Get the context locale key.
*/
public function getLocaleContextKey(): string
{
return sprintf('%s::%s', TranslatorInterface::class, 'locale');
}
/**
* Get the default locale being used.
*/
public function getLocale(): string
{
return $this->locale;
$locale = Context::get($this->getLocaleContextKey());
return (string) ($locale ?? $this->locale);
}
/**
@ -328,7 +339,7 @@ class Translator implements TranslatorInterface
*/
public function setLocale(string $locale)
{
$this->locale = $locale;
Context::set($this->getLocaleContextKey(), $locale);
}
/**
@ -371,7 +382,7 @@ class Translator implements TranslatorInterface
*/
protected function localeForChoice(?string $locale): string
{
return $locale ?: $this->locale ?: $this->fallback;
return $locale ?: $this->locale() ?: $this->fallback;
}
/**
@ -453,16 +464,13 @@ class Translator implements TranslatorInterface
*/
protected function localeArray(?string $locale): array
{
return array_filter([$locale ?: $this->locale, $this->fallback]);
return array_filter([$locale ?: $this->locale(), $this->fallback]);
}
/**
* Parse an array of basic segments.
*
* @param array $segments
* @return array
*/
protected function parseBasicSegments(array $segments)
protected function parseBasicSegments(array $segments): array
{
// The first segment in a basic array will always be the group, so we can go
// ahead and grab that segment. If there is only one total segment we are

View File

@ -286,6 +286,25 @@ class TranslatorTest extends TestCase
$this->assertEquals('foo baz', $t->getFromJson('foo :message', ['message' => 'baz']));
}
public function testSetLocale()
{
$t = new Translator($this->getLoader(), 'en');
$this->assertEquals('en', $t->getLocale());
parallel([
function () use ($t) {
$this->assertEquals('en', $t->getLocale());
$t->setLocale('zh_CN');
$this->assertEquals('zh_CN', $t->getLocale());
},
function () use ($t) {
$this->assertEquals('en', $t->getLocale());
$t->setLocale('zh_HK');
$this->assertEquals('zh_HK', $t->getLocale());
},
]);
$this->assertEquals('en', $t->getLocale());
}
protected function getLoader()
{
return Mockery::mock(TranslatorLoaderInterface::class);