国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

hyperf 十四 國際化

這篇具有很好參考價值的文章主要介紹了hyperf 十四 國際化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

官方網(wǎng)址:Hyperf

一 安裝

composer require hyperf/translation:v2.2.33

二 配置

1、設(shè)置語言文件

文件結(jié)構(gòu):

????????/storage/languages/en/messages.php

????????/storage/languages/zh_CH/messages.php

// storage/languages/en/messages.php
return [
    'welcome' => 'Welcome to our application :test :test2',
    'test' => '{2} TEST1|[3,10] TEST2|[20,*] TEST3',
];


// storage/languages/zh_CH/messages.php
return [
    'welcome' => '歡迎-使用  :test :test2',
];

2、設(shè)置配置文件

創(chuàng)建文件 /config/autoload/translation.php。

#/config/autoload/translation.php
return [
    // 默認(rèn)語言
    'locale' => 'zh_CN',
    // 回退語言,當(dāng)默認(rèn)語言的語言文本沒有提供時,就會使用回退語言的對應(yīng)語言文本
    'fallback_locale' => 'en',
    // 語言文件存放的文件夾
    'path' => BASE_PATH . '/storage/languages',
];

三 使用

1、臨時設(shè)置語言

// storage/languages/zh_CH/messages.php
return [
    'welcome' => '歡迎-使用',
];

#/config/autoload/translation.php
return [
    // 默認(rèn)語言
    'locale' => 'en',
    // 回退語言,當(dāng)默認(rèn)語言的語言文本沒有提供時,就會使用回退語言的對應(yīng)語言文本
    'fallback_locale' => 'en',
    // 語言文件存放的文件夾
    'path' => BASE_PATH . '/storage/languages',
];

//App\Controller\TestController
use Hyperf\Di\Annotation\Inject;
use Hyperf\Contract\TranslatorInterface;

class TestController
{
    /**
     * @Inject
     * @var TranslatorInterface
     */
    private $translator;
    
    public function index()
    {
        $value = $this->translator->trans('messages.welcome', [], 'zh_CN');
        var_dump($value);
    }
}

# 輸出
string(26) "歡迎-使用"

2、全局函數(shù)

// storage/languages/zh_CH/messages.php
return [
    'welcome' => '歡迎-使用',
    'test1' => '測試',
];

// config/autoload/translation.php
return [
    // 默認(rèn)語言
    'locale' => 'zn_CH',
    // 回退語言,當(dāng)默認(rèn)語言的語言文本沒有提供時,就會使用回退語言的對應(yīng)語言文本
    'fallback_locale' => 'en',
    // 語言文件存放的文件夾
    'path' => BASE_PATH . '/storage/languages',
];

// App\Controller\TestController
class TestController
{
    /**
     * @Inject
     * @var TranslatorInterface
     */
    private $translator;
    
    public function test2()
    {
        echo __('message.welcome') . "\n"; //歡迎-使用
        echo trans('message.welcome') . "\n";//歡迎-使用
    }
}

4、自定義占位符

// storage/languages/en/messages.php
return [
    'welcome' => 'Welcome to our application :test :test2',
];

// config/autoload/translation.php
return [
    // 默認(rèn)語言
    'locale' => 'en',
    // 回退語言,當(dāng)默認(rèn)語言的語言文本沒有提供時,就會使用回退語言的對應(yīng)語言文本
    'fallback_locale' => 'en',
    // 語言文件存放的文件夾
    'path' => BASE_PATH . '/storage/languages',
];

// App\Controller\TestController
class TestController
{
    /**
     * @Inject
     * @var TranslatorInterface
     */
    private $translator;
    
    public function test2()
    {
        echo __('message.welcome',['test'=>'qqq','test2':'aaa']) . "\n"; 
        //Welcome to our application qqq aaa
        echo trans('message.welcome',['test'=>'qqq','test2':'aaa']) . "\n";
        //Welcome to our application qqq aaa
    }
}

5、復(fù)數(shù)處理

// storage/languages/en/messages.php
return [
    'test' => '{2} TEST1|[3,10] TEST2|[20,*] TEST3',
];

// config/autoload/translation.php
return [
    // 默認(rèn)語言
    'locale' => 'en',
    // 回退語言,當(dāng)默認(rèn)語言的語言文本沒有提供時,就會使用回退語言的對應(yīng)語言文本
    'fallback_locale' => 'en',
    // 語言文件存放的文件夾
    'path' => BASE_PATH . '/storage/languages',
];

// App\Controller\TestController
class TestController
{
    /**
     * @Inject
     * @var TranslatorInterface
     */
    private $translator;
    
    public function test2()
    {
        echo $this->translator->transChoice('message.test',0)."\n";
        echo trans_choice('message.test',0) . "\n"; 
        echo trans_choice('message.test',2) . "\n"; 
        echo trans_choice('message.test',4) . "\n";
        echo trans_choice('message.test',22) . "\n";  
    }
}

//輸出
 TEST1
 TEST1
TEST1
TEST2
TEST3

四 詳解

1、調(diào)用

多語言的調(diào)用從注入開始,即Hyperf\Translation\Translator::__construct(TranslatorLoaderInterface $loader, string $locale)方法。根據(jù)配置文件TranslatorLoaderInterface 對應(yīng)Hyperf\Translation\FileLoaderFactory類。讀取配置文件/storage/languages/translation.path,并返回Hyperf\Translation\FileLoader類。即注入到Translator的構(gòu)造的TranslatorLoaderInterface 實(shí)體類是FileLoader。

若無/storage/languages/translation.path配置文件,可使用默認(rèn)配置vendor\hyperf\translation\publish\translation.php生成。

php bin/hyperf.php vendor:publish hyperf/translation

使用的語言標(biāo)志比如en、zn_ch,在上下文中讀取和設(shè)置。

Translator內(nèi)調(diào)用順序:

Translator::trans()->Translator::get()->Translator::getLine()->Translator::load()->FileLoader::load()

根據(jù)FileLoader::load()調(diào)用FileLoader::loadJsonPaths(),可以將不同語言的不同文件統(tǒng)一放到j(luò)son文件中,使用FileLoader::addJsonPath()設(shè)置對應(yīng)文件。會便利對應(yīng)文件加載內(nèi)容,就是對應(yīng)語言的全部內(nèi)容。

根據(jù)FileLoader::load()調(diào)用FileLoader::loadPath(),加載對應(yīng)文件。比如翻譯a.b,a是對應(yīng)語言的組名,b對應(yīng)是鍵名,文件是/storage/languages/對應(yīng)語言/a.php。

根據(jù)FileLoader::load()調(diào)用FileLoader::loadNamespaced(),用命名空間加載。這里所謂命名空間就是,對比默認(rèn)路徑,設(shè)置一個鍵名對應(yīng)非默認(rèn)路徑。也是調(diào)用loadPath()實(shí)現(xiàn),不過傳入非默認(rèn)路徑,用命名空間獲取路徑值,用FileLoader::addNamespace()設(shè)置命名空間和路徑值。

Translator::trans()->Translator::get()->Translator::getLine()->Translator::makeReplacements()->sTranslator::ortReplacements()

根據(jù)Translator::ortReplacements(),查詢字符串中":占位符"或":占位符全大寫"或":占位符首字母大寫"。

Translator::transChoice()->Translator::choice()->Translator::makeReplacements()->Translator::getSelector()->MessageSelector::choose()

Translator::choice()也調(diào)用Translator::get()但是中心加載了本地語言的標(biāo)識。Translator::getSelector()將替換值作為數(shù)字,MessageSelector::choose()解析字符串、替換字符換中對應(yīng)數(shù)字條件字符,并根據(jù)不同語言處理數(shù)字,返回最終結(jié)果。

全局函數(shù)在vendor\hyperf\translation\src\Function.php中,在其composer.json中自動加載。文章來源地址http://www.zghlxwxcb.cn/news/detail-681353.html

2、源碼

#Hyperf\Translation\Translator
class Translator implements TranslatorInterface
{
    public function __construct(TranslatorLoaderInterface $loader, string $locale)
    {
        $this->loader = $loader;
        $this->locale = $locale;
    }
    public function trans(string $key, array $replace = [], ?string $locale = null)
    {
        return $this->get($key, $replace, $locale);
    }
     public function transChoice(string $key, $number, array $replace = [], ?string $locale = null): string
    {
        return $this->choice($key, $number, $replace, $locale);
    }
    public function get(string $key, array $replace = [], ?string $locale = null, bool $fallback = true)
    {
        [$namespace, $group, $item] = $this->parseKey($key);

        // Here we will get the locale that should be used for the language line. If one
        // 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()];
        foreach ($locales as $locale) {
            if (!is_null($line = $this->getLine(
                $namespace,
                $group,
                $locale,
                $item,
                $replace
            ))) {
                break;
            }
        }

        // If the line doesn't exist, we will return back the key which was requested as
        // that will be quick to spot in the UI if language keys are wrong or missing
        // from the application's language files. Otherwise we can return the line.
        return $line ?? $key;
    }
     public function choice(string $key, $number, array $replace = [], ?string $locale = null): string
    {
        $line = $this->get(
            $key,
            $replace,
            $locale = $this->localeForChoice($locale)
        );

        // If the given "number" is actually an array or countable we will simply count the
        // number of elements in an instance. This allows developers to pass an array of
        // items without having to count it on their end first which gives bad syntax.
        if (is_array($number) || $number instanceof Countable) {
            $number = count($number);
        }

        $replace['count'] = $number;

        return $this->makeReplacements(
            $this->getSelector()->choose($line, $number, $locale),
            $replace
        );
    }
    protected function localeForChoice(?string $locale): string
    {
        return $locale ?: $this->locale() ?: $this->fallback;
    }
     protected function getLine(string $namespace, string $group, string $locale, $item, array $replace)
    {
        $this->load($namespace, $group, $locale);
        if (!is_null($item)) {
            $line = Arr::get($this->loaded[$namespace][$group][$locale], $item);
        } else {
            // do for hyperf Arr::get
            $line = $this->loaded[$namespace][$group][$locale];
        }
        if (is_string($line)) {
            return $this->makeReplacements($line, $replace);
        }

        if (is_array($line) && count($line) > 0) {
            foreach ($line as $key => $value) {
                $line[$key] = $this->makeReplacements($value, $replace);
            }

            return $line;
        }

        return null;
    }
    
}

#Hyperf\Translation\FileLoaderFactory
class FileLoaderFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $config = $container->get(ConfigInterface::class);
        $files = $container->get(Filesystem::class);
        $path = $config->get('translation.path', BASE_PATH . '/storage/languages');

        return make(FileLoader::class, compact('files', 'path'));
    }
}

#Hyperf\Translation\FileLoader 
class FileLoader implements TranslatorLoaderInterface
{
    public function __construct(Filesystem $files, string $path)
    {
        $this->path = $path;
        $this->files = $files;
    }
    public function load(string $locale, string $group, ?string $namespace = null): array
    {
        if ($group === '*' && $namespace === '*') {
            return $this->loadJsonPaths($locale);
        }

        if (is_null($namespace) || $namespace === '*') {
            return $this->loadPath($this->path, $locale, $group);
        }

        return $this->loadNamespaced($locale, $group, $namespace);
    }
     public function addNamespace(string $namespace, string $hint)
    {
        $this->hints[$namespace] = $hint;
    }
    public function addJsonPath(string $path)
    {
        $this->jsonPaths[] = $path;
    }
    protected function loadNamespaced(string $locale, string $group, string $namespace): array
    {
        if (isset($this->hints[$namespace])) {
            $lines = $this->loadPath($this->hints[$namespace], $locale, $group);

            return $this->loadNamespaceOverrides($lines, $locale, $group, $namespace);
        }

        return [];
    }
    protected function loadPath(string $path, string $locale, string $group): array
    {
        if ($this->files->exists($full = "{$path}/{$locale}/{$group}.php")) {
            return $this->files->getRequire($full);
        }

        return [];
    }
    protected function loadJsonPaths(string $locale): iterable
    {
        return collect(array_merge($this->jsonPaths, [$this->path]))
            ->reduce(function ($output, $path) use ($locale) {
                if ($this->files->exists($full = "{$path}/{$locale}.json")) {
                    $decoded = json_decode($this->files->get($full), true);

                    if (is_null($decoded) || json_last_error() !== JSON_ERROR_NONE) {
                        throw new RuntimeException("Translation file [{$full}] contains an invalid JSON structure.");
                    }

                    $output = array_merge($output, $decoded);
                }

                return $output;
            }, []);
    }
}

#Hyperf\Translation\MessageSelector
class MessageSelector
{
public function choose(string $line, $number, string $locale)
    {
        $segments = explode('|', $line);

        if (($value = $this->extract($segments, $number)) !== null) {
            return trim($value);
        }

        $segments = $this->stripConditions($segments);

        $pluralIndex = $this->getPluralIndex($locale, $number);

        if (count($segments) === 1 || ! isset($segments[$pluralIndex])) {
            return $segments[0];
        }

        return $segments[$pluralIndex];
    }
 private function extract(array $segments, $number)
    {
        foreach ($segments as $part) {
            if (! is_null($line = $this->extractFromString($part, $number))) {
                return $line;
            }
        }
    }
private function stripConditions(array $segments): array
    {
        return collect($segments)->map(function ($part) {
            return preg_replace('/^[\{\[]([^\[\]\{\}]*)[\}\]]/', '', $part);
        })->all();
    }
private function stripConditions(array $segments): array
    {
        return collect($segments)->map(function ($part) {
            return preg_replace('/^[\{\[]([^\[\]\{\}]*)[\}\]]/', '', $part);
        })->all();
    }
public function getPluralIndex(string $locale, int $number): int
    {
    switch ($locale) {
            ……
            case 'en':
            ……
            return ($number == 1) ? 0 : 1;
    }
    ……
    }
}
#vendor\hyperf\translation\src\Function.php
if (! function_exists('__')) {
    function __(string $key, array $replace = [], ?string $locale = null)
    {
        $translator = ApplicationContext::getContainer()->get(TranslatorInterface::class);
        return $translator->trans($key, $replace, $locale);
    }
}

if (! function_exists('trans')) {
    function trans(string $key, array $replace = [], ?string $locale = null)
    {
        return __($key, $replace, $locale);
    }
}

if (! function_exists('trans_choice')) {
    function trans_choice(string $key, $number, array $replace = [], ?string $locale = null): string
    {
        $translator = ApplicationContext::getContainer()->get(TranslatorInterface::class);
        return $translator->transChoice($key, $number, $replace, $locale);
    }
}

到了這里,關(guān)于hyperf 十四 國際化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • springcloud微服務(wù)國際化

    springcloud微服務(wù)國際化

    單體應(yīng)用完成國際化還是比較簡單的,可以看下面的示例代碼。 引入必要的依賴 創(chuàng)建一個攔截器 創(chuàng)建一個配置類 然后在 resource 下創(chuàng)建 i18n 目錄,選中右鍵 New = Resource Bundle 填入 base name ,選擇 Project locales ,再 Add All ,確定即可。 打開配置文件,填寫對應(yīng)的中英文數(shù)據(jù) 配置

    2023年04月09日
    瀏覽(109)
  • SpringBoot復(fù)習(xí):(36)國際化

    SpringBoot復(fù)習(xí):(36)國際化

    一、Resources目錄下建立一個目錄(比如international)來存儲資源文件 message.properties 空的,但不能沒有 message_zh_CN.properties message_en_us.properties 二、自動配置類MessageSourceAutoConfiguration 常量MESSAGE_SOURCE_BEAN_NAME為messageSource,也就是有這個名字的bean,則自動配置失效。 因?yàn)橛蠤Conditional(R

    2024年02月13日
    瀏覽(29)
  • vue2+element-ui使用vue-i18n進(jìn)行國際化的多語言/國際化

    vue2+element-ui使用vue-i18n進(jìn)行國際化的多語言/國際化

    注意:vue2.0要用8版本的,使用9版本的會報錯 在src目錄下,創(chuàng)建新的文件夾,命名為i18n zh.js en.js index.js main.js 使用方式一 效果圖 使用方式二 效果圖 使用方式三,在 效果圖 ` 注意:這種方式存在更新this.$i18n.locale的值時無法自動切換的問題,需要刷新頁面才能切換語言。解

    2024年02月07日
    瀏覽(24)
  • 第七十一回:國際化設(shè)置

    我們在上一章回中介紹了Card Widget相關(guān)的內(nèi)容,本章回中將介紹 國際化設(shè)置 .閑話休提,讓我們一起Talk Flutter吧。 我們在這里說的國際化設(shè)置是指在App設(shè)置相關(guān)操作,這樣可以讓不同國家的用戶使用App時呈現(xiàn)不同的語言??傊?,就是通過相關(guān)的操作,讓App支持多個國家的語言

    2024年02月11日
    瀏覽(100)
  • Android國際化各國語言簡寫

    2024年02月16日
    瀏覽(24)
  • Spring Boot實(shí)現(xiàn)國際化

    config controller 在Thymeleaf模板中引用國際化消息:

    2024年01月23日
    瀏覽(20)
  • Flutter GetX 之 國際化

    今天給大家介紹一下 GetX 的國際化功能,在日常開發(fā)過程中,我們經(jīng)常會使用到國際化功能,需要們的應(yīng)用支持 國際化,例如我們需要支持 簡體、繁體、英文等等。 上幾篇文章介紹了GetX的 路由管理 和 狀態(tài)管理,看到大家的點(diǎn)贊和收藏,還是很開心的,說明這兩篇文章給大

    2024年01月19日
    瀏覽(33)
  • 如何優(yōu)雅的實(shí)現(xiàn)前端國際化?

    如何優(yōu)雅的實(shí)現(xiàn)前端國際化?

    JavaScript 中每個常見問題都有許多成熟的解決方案。當(dāng)然,國際化 (i18n) 也不例外,有很多成熟的 JavaScript i18n 庫可供選擇,下面就來分享一些熱門的前端國際化庫! i18next 是一個用 JavaScript 編寫的全面的國際化框架,提供標(biāo)準(zhǔn)的 i18n 功能,包括復(fù)數(shù)、上下文、插值、格式等。

    2024年01月23日
    瀏覽(38)
  • Spring MVC(三) 國際化

    隨著全球化的加速發(fā)展,Web應(yīng)用的多語言支持變得越來越重要。對于開發(fā)者來說,如何實(shí)現(xiàn)應(yīng)用的國際化成為了一個不可忽視的問題。作為Java Web開發(fā)的重要框架,Spring MVC在處理國際化方面有著豐富的功能和靈活的解決方案。本文將探討Spring MVC的國際化部分內(nèi)容,并通過自己

    2024年01月18日
    瀏覽(24)
  • SpringBoot集成國際化多語言配置

    SpringBoot集成國際化多語言配置

    在當(dāng)今全球化的環(huán)境下,為了更好地滿足用戶的多語言需求,越來越多的應(yīng)用程序需要支持國際化多語言配置。Spring Boot作為一種快速開發(fā)框架,提供了方便的國際化支持,使得應(yīng)用程序可以輕松地適應(yīng)不同的語言環(huán)境。通過集成Spring Boot的國際化多語言配置,應(yīng)用程序可以根

    2024年02月07日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包