如何在其他框架中使用 Hyperf 國際化元件

李銘昕發表於2020-04-08

前段時間有同學在群裡提問,如何在其他框架裡引用 Hyperf 國際化元件,並提供了對應的 ISSUE

Issue 中的錯誤其實很簡單,就是 Hyperf\Utils\ApplicationContext 中沒有存入對應的 Container,為了更方便的接入 Hyperf 其他的元件,Hyperf 官方提供了一個新的元件 hyperf/pimple

這是一個基於 pimple/pimple 實現的符合 PSR11 規範的容器元件。接下來讓我正式開始接入 國際化元件,以下以 EasySwoole 為例。

接入指南

因為 EasySwoole 的容器元件暫時並沒有實現 PSR11 規範,所以無法直接使用。

  • 首先引入相關元件
composer require "hyperf/pimple:1.1.*"
composer require "hyperf/translation:1.1.*"
composer require "hyperf/config:1.1.*"
  • 新增 國際化相關的 Provider

TranslatorLoaderProvider

<?php

declare(strict_types=1);

namespace App\Provider;

use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\ContainerInterface;
use Hyperf\Contract\TranslatorLoaderInterface;
use Hyperf\Pimple\ProviderInterface;
use Hyperf\Translation\FileLoader;
use Hyperf\Utils\Filesystem\Filesystem;

class TranslatorLoaderProvider implements ProviderInterface
{
    public function register(ContainerInterface $container)
    {
        $container->set(TranslatorLoaderInterface::class, function () use ($container) {
            $config = $container->get(ConfigInterface::class);
            $files = $container->get(Filesystem::class);
            $path = $config->get('translation.path');

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

TranslatorProvider

<?php

declare(strict_types=1);

namespace App\Provider;

use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\ContainerInterface;
use Hyperf\Contract\TranslatorInterface;
use Hyperf\Contract\TranslatorLoaderInterface;
use Hyperf\Pimple\ProviderInterface;
use Hyperf\Translation\Translator;

class TranslatorProvider implements ProviderInterface
{
    public function register(ContainerInterface $container)
    {
        $container->set(TranslatorInterface::class, function () use ($container) {
            $config = $container->get(ConfigInterface::class);
            $locale = $config->get('translation.locale');
            $fallbackLocale = $config->get('translation.fallback_locale');

            $loader = $container->get(TranslatorLoaderInterface::class);

            $translator = make(Translator::class, compact('loader', 'locale'));
            $translator->setFallback((string) $fallbackLocale);

            return $translator;
        });
    }
}
  • EasySwoole 事件註冊器在 EasySwooleEvent.php 中,所以我們需要在 initialize() 中初始化我們的容器和國際化元件。

以下 Config 元件,可以自行封裝,這裡方便起見直接配置。

<?php

declare(strict_types=1);

namespace EasySwoole\EasySwoole;

use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;
use EasySwoole\Http\Request;
use EasySwoole\Http\Response;
use Hyperf\Config\Config;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Pimple\ContainerFactory;
use App\Provider\TranslatorProvider;
use App\Provider\TranslatorLoaderProvider;

class EasySwooleEvent implements Event
{
    public static function initialize()
    {
        date_default_timezone_set('Asia/Shanghai');
        $container = (new ContainerFactory([
            TranslatorProvider::class,
            TranslatorLoaderProvider::class,
        ]))();
        $container->set(ConfigInterface::class, new Config([
            'translation' => [
                'locale' => 'zh_CN',
                'fallback_locale' => 'en',
                'path' => EASYSWOOLE_ROOT . '/storage/languages',
            ],
        ]));
    }
}
  • 修改控制器,使用國際化元件
<?php

declare(strict_types=1);

namespace App\HttpController;

use EasySwoole\Http\AbstractInterface\Controller;
use Hyperf\Contract\TranslatorInterface;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Codec\Json;

class Index extends Controller
{
    public function index()
    {
        $container = ApplicationContext::getContainer();
        $translator = $container->get(TranslatorInterface::class);

        $data = [
            'message' => $translator->trans('message.hello', ['name' => 'Hyperf']),
        ];

        $this->response()->write(Json::encode($data));
    }
}
  • 新增國際化配置
// storage/languages/en/message.php
return [
    'hello' => 'Hello :name',
];

// storage/languages/zh_CN/message.php
return [
    'hello' => '你好 :name',
];
  • 測試
$ curl http://127.0.0.1:9501/
{"message":"你好 Hyperf"}

寫在最後

Hyperf 是基於 Swoole 4.4+ 實現的高效能、高靈活性的 PHP 協程框架,內建協程伺服器及大量常用的元件,效能較傳統基於 PHP-FPM 的框架有質的提升,提供超高效能的同時,也保持著極其靈活的可擴充套件性,標準元件均基於 PSR 標準 實現,基於強大的依賴注入設計,保證了絕大部分元件或類都是 可替換 與 可複用 的。

框架元件庫除了常見的協程版的 MySQL 客戶端、Redis 客戶端,還為您準備了協程版的 Eloquent ORM、WebSocket 服務端及客戶端、JSON RPC 服務端及客戶端、GRPC 服務端及客戶端、Zipkin/Jaeger (OpenTracing) 客戶端、Guzzle HTTP 客戶端、Elasticsearch 客戶端、Consul 客戶端、ETCD 客戶端、AMQP 元件、Apollo 配置中心、阿里雲 ACM 應用配置管理、ETCD 配置中心、基於令牌桶演算法的限流器、通用連線池、熔斷器、Swagger 文件生成、Swoole Tracker、Blade 和 Smarty 檢視引擎、Snowflake 全域性ID生成器 等元件,省去了自己實現對應協程版本的麻煩。

Hyperf 還提供了 基於 PSR-11 的依賴注入容器、註解、AOP 面向切面程式設計、基於 PSR-15 的中介軟體、自定義程式、基於 PSR-14 的事件管理器、Redis/RabbitMQ 訊息佇列、自動模型快取、基於 PSR-16 的快取、Crontab 秒級定時任務、Translation 國際化、Validation 驗證器 等

本作品採用《CC 協議》,轉載必須註明作者和本文連結

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

相關文章