toBento / service-translation
使您能够在应用程序中支持多种语言。
1.0.3
2023-06-18 10:14 UTC
Requires
- php: >=8.0
- psr/log: ^1.1 || ^2.0 || ^3.0
- tobento/service-dir: ^1.0
- tobento/service-filesystem: ^1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.0
README
使用翻译服务可以轻松翻译消息。
目录
入门
使用此命令添加运行翻译服务的最新版本。
composer require tobento/service-translation
要求
- PHP 8.0 或更高版本
亮点
- 框架无关,适用于任何项目
- 解耦设计
简单示例
以下是一个如何使用翻译服务的简单示例
use Tobento\Service\Translation\Translator; use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\Modifier\ParameterReplacer; use Tobento\Service\Translation\Modifier\Pluralization; use Tobento\Service\Translation\MissingTranslationHandler; $translator = new Translator( new Resources( new Resource('*', 'de', [ 'Hello World' => 'Hallo Welt', ]), ), new Modifiers( new Pluralization(), new ParameterReplacer(), ), new MissingTranslationHandler(), 'en', ); var_dump($translator->trans('Hello World')); // string(11) "Hello World" var_dump($translator->trans('Hello World', [], 'de')); // string(10) "Hallo Welt"
文档
翻译器
创建翻译器
use Tobento\Service\Translation\Translator; use Tobento\Service\Translation\TranslatorInterface; use Tobento\Service\Translation\LocaleAware; use Tobento\Service\Translation\ResourcesAware; use Tobento\Service\Translation\ModifiersAware; use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\Modifier\ParameterReplacer; use Tobento\Service\Translation\MissingTranslationHandler; $translator = new Translator( resources: new Resources( new Resource('*', 'de', [ 'Hello World' => 'Hallo Welt', ]), ), modifiers: new Modifiers( new ParameterReplacer(), ), missingTranslationHandler: new MissingTranslationHandler(), locale: 'en', localeFallbacks: ['de' => 'en'], localeMapping: ['de' => 'de-CH'], ); var_dump($translator instanceof TranslatorInterface); // bool(true) var_dump($translator instanceof LocaleAware); // bool(true) var_dump($translator instanceof ResourcesAware); // bool(true) var_dump($translator instanceof ModifiersAware); // bool(true)
翻译器接口
use Tobento\Service\Translation\TranslatorInterface; $translated = $translator->trans( message: 'Hi :name', parameters: [':name' => 'John'], locale: 'de' );
区域感知
use Tobento\Service\Translation\LocaleAware; // set the default locale: $translator->setLocale('de'); // get the default locale: var_dump($translator->getLocale()); // string(2) "de" // set the locale fallbacks: $translator->setLocaleFallbacks(['de' => 'en']); // get the locale fallbacks: var_dump($translator->getLocaleFallbacks()); // array(1) { ["de"]=> string(2) "en" } // set the locale mapping: $translator->setLocaleMapping(['de' => 'de-CH']); // get the locale mapping: var_dump($translator->getLocaleMapping()); // array(1) { ["de"]=> string(5) "de-CH" }
资源感知
use Tobento\Service\Translation\ResourcesAware; use Tobento\Service\Translation\ResourcesInterface; // get the resources: var_dump($translator->resources() instanceof ResourcesInterface); // bool(true) // returns the translations of the specified resource: $translations = $translator->getResource( name: '*', locale: 'de' // or null to use default ); var_dump($translations); // array(1) { ["Hello World"]=> string(10) "Hallo Welt" } // returns a new instance with the specified resources: $translator = $translator->withResources( resources: $resources // ResourcesInterface );
修饰符感知
有关更多详细信息,请参阅修饰符。
use Tobento\Service\Translation\ModifiersAware; use Tobento\Service\Translation\ModifiersInterface; // get the modifiers: var_dump($translator->modifiers() instanceof ModifiersInterface); // bool(true) // returns a new instance with the specified modifiers: $translator = $translator->withModifiers( modifiers: $modifiers // ModifiersInterface );
翻译消息
use Tobento\Service\Translation\Translator; use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\Modifier\Pluralization; use Tobento\Service\Translation\Modifier\ParameterReplacer; use Tobento\Service\Translation\MissingTranslationHandler; $translator = new Translator( resources: new Resources( new Resource('*', 'de', [ 'Hi :name' => 'Hi :name', 'It takes :minutes minute|It takes :minutes minutes' => 'Es dauert :minutes Minute|Es dauert :minutes Minuten' ]), ), modifiers: new Modifiers( new Pluralization(), new ParameterReplacer(), ), missingTranslationHandler: new MissingTranslationHandler(), locale: 'en', localeFallbacks: ['de' => 'en'], ); $translated = $translator->trans( message: 'Hi :name', parameters: [':name' => 'John'], locale: 'de' ); var_dump($translated); // string(7) "Hi John" $translated = $translator->trans( message: 'It takes :minutes minute|It takes :minutes minutes', parameters: [':minutes' => 5, 'count' => 5], locale: 'de' ); var_dump($translated); // string(19) "Es dauert 5 Minuten"
默认情况下,资源将按优先级排序!
使用特定资源
请注意,命名资源仅在第一次资源请求时加载。
以 "*" 命名的资源始终加载。
use Tobento\Service\Translation\Translator; use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\MissingTranslationHandler; $translator = new Translator( resources: new Resources( new Resource('shop', 'de', [ 'noProducts' => 'Keine Produkte', 'No items in your shopping bag.' => 'Keine Artikel sind in deinem Warenkorb.', ]), ), modifiers: new Modifiers(), missingTranslationHandler: new MissingTranslationHandler(), locale: 'en', localeFallbacks: ['de' => 'en'], ); // with dot notation $translated = $translator->trans( message: 'shop.noProducts', locale: 'de' ); var_dump($translated); // string(14) "Keine Produkte" // with src parameter $translated = $translator->trans( message: 'No items in your shopping bag.', parameters: ['src' => 'shop'], locale: 'de' ); var_dump($translated); // string(39) "Keine Artikel sind in deinem Warenkorb."
资源
创建资源
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\ResourcesInterface; use Tobento\Service\Translation\Resource; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], group: 'front', priority: 10, ), ); var_dump($resources instanceof ResourcesInterface); // bool(true)
添加资源
您可以使用 add 方法添加资源
添加资源
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources(); $resources->add(new Resource('*', 'de', [ 'Hello World' => 'Hallo Welt', ]));
添加资源
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources(); $resources->add(new Resources( new Resource('*', 'de', [ 'Hello World' => 'Hallo Welt', ]), ));
筛选资源
您可以使用返回新实例的过滤方法。
过滤
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\ResourceInterface; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], group: 'front', ), new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], group: 'back', ), ); // filter by group: $resources = $resources->filter( fn(ResourceInterface $r): bool => $r->group() === 'front' );
区域
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], ), new Resource( name: '*', locale: 'de', translations: ['Hello World' => 'Hallo Welt'], ), ); // filter by locale: $resources = $resources->locale('en');
区域
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], ), new Resource( name: '*', locale: 'de', translations: ['Hello World' => 'Hallo Welt'], ), ); // filter by locales: $resources = $resources->locales(['en', 'de']);
名称
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources( new Resource( name: 'shop', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], ), new Resource( name: 'shop', locale: 'de', translations: ['Hello World' => 'Hallo Welt'], ), ); // filter by name: $resources = $resources->name('shop');
排序资源
按优先级排序
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], priority: 10, ), new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], priority: 15, ), ); // sort by priority: $resources = $resources->sort();
按回调排序
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\ResourceInterface; $resources = new Resources( new Resource( name: 'users', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], priority: 10, ), new Resource( name: 'shop', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], priority: 15, ), ); // sort by name: $resources = $resources->sort( fn(ResourceInterface $a, ResourceInterface $b): int => $a->name() <=> $b->name() );
获取资源/翻译
全部
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\ResourceInterface; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], ), ); foreach($resources->all() as $resource) { var_dump($resource instanceof ResourceInterface); // bool(true) var_dump($resource->name()); // string(1) "*" var_dump($resource->locale()); // string(2) "en" var_dump($resource->group()); // string(7) "default" var_dump($resource->priority()); // int(0) var_dump($resource->translations()); // array(1) { ["Hello World"]=> string(10) "Hallo Welt" } }
翻译
use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; $resources = new Resources( new Resource( name: '*', locale: 'en', translations: ['Hello World' => 'Hallo Welt'], priority: 10, ), ); $translations = $resources->locale('en')->translations(); /*Array ( [Hello World] => Hallo Welt )*/
⚠️ 如果您已添加(子或懒)资源,则必须在 all() 或 translations() 方法之前调用 locale() 或 locales(),否则它们将不会创建。
foreach($resources->locale('en')->all() as $resource) { var_dump($resource instanceof ResourceInterface); // bool(true) }
文件资源
创建文件资源
use Tobento\Service\Translation\FilesResources; use Tobento\Service\Dir\Dirs; use Tobento\Service\Translation\ResourcesInterface; $resources = new FilesResources( (new Dirs())->dir(dir: 'private/trans/', group: 'front', priority: 10) ); var_dump($resources instanceof ResourcesInterface); // bool(true)
目录结构
以区域开头的文件存储为 *
资源名称。它们将在第一次翻译请求时全部检索并合并。
不以区域开头的文件仅在第一次资源请求时加载。此外,名为 routes.shop.json
和 routes.blog.json
的文件将作为资源名称 routes
合并。
private/
trans/
en/
en.php
en.json
en-shop.json
shop.json
routes.shop.json
routes.blog.json
de-CH/
de-CH.json
de-CH-shop.json
shop.json
routes.shop.json
支持的文件
当前支持的文件是 json 和 php。
json
{ "Using Real Message": "Using Real Message", "usingKeywordMessage": "Using Keyword Message" }
php
return [ 'Using Real Message' => 'Using Real Message', 'usingKeywordMessage' => 'Using Keyword Message', ];
支持其他文件
您可以通过提供自己的资源工厂来支持其他文件
use Tobento\Service\Translation\FilesResources; use Tobento\Service\Dir\Dirs; use Tobento\Service\Translation\ResourceFactory; use Tobento\Service\Translation\ResourceInterface; use Tobento\Service\Filesystem\File; class CustomResourceFactory extends ResourceFactory { /** * Create a new Resource from file. * * @param string|File $file * @param string $locale * @param string $group * @param int $priority * @return ResourceInterface */ public function createResourceFromFile( string|File $file, string $locale, string $group = 'default', int $priority = 0, ): ResourceInterface { // Create your custom resource for the specific file extension // Otherwise use parent return parent::createResourceFromFile($file, $locale, $group, $priority); } } $resources = new FilesResources( (new Dirs())->dir(dir: 'private/trans/', group: 'front', priority: 10), new CustomResourceFactory() );
修饰符
创建修饰符
use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\ModifiersInterface; use Tobento\Service\Translation\Modifier\ParameterReplacer; $modifiers = new Modifiers( new ParameterReplacer(), ); var_dump($modifiers instanceof ModifiersInterface); // bool(true)
添加修饰符
use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\Modifier\ParameterReplacer; $modifiers = new Modifiers(); $modifiers->add(new ParameterReplacer());
获取所有修饰符
use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\Modifier\ParameterReplacer; use Tobento\Service\Translation\ModifierInterface; $modifiers = new Modifiers(new ParameterReplacer()); $allModifiers = $modifiers->all(); // array<int, ModifierInterface>
修改消息
use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\Modifier\ParameterReplacer; $modifiers = new Modifiers( new ParameterReplacer(), ); [$message, $parameters] = $modifiers->modify( message: 'Hi :name', parameters: [':name' => 'John'], ); var_dump($message); // string(7) "Hi John"
复数化
use Tobento\Service\Translation\Modifier\Pluralization; $modifier = new Pluralization(key: 'count'); [$message, $parameters] = $modifier->modify( message: 'There is one apple|There are many apples', parameters: ['count' => 5], ); var_dump($message); // string(21) "There are many apples" [$message, $parameters] = $modifier->modify( message: 'There is one apple|There are many apples', parameters: ['count' => 1], ); var_dump($message); // string(18) "There is one apple"
参数替换器
use Tobento\Service\Translation\Modifier\ParameterReplacer; $modifier = new ParameterReplacer(); [$message, $parameters] = $modifier->modify( message: 'Hi :name', parameters: [':name' => 'John'], ); var_dump($message); // string(7) "Hi John"
缺失翻译处理器
您可以为记录缺失的消息添加记录器
use Tobento\Service\Translation\Translator; use Tobento\Service\Translation\Resources; use Tobento\Service\Translation\Resource; use Tobento\Service\Translation\Modifiers; use Tobento\Service\Translation\MissingTranslationHandler; use Psr\Log\LoggerInterface; use Monolog\Logger; use Monolog\Handler\StreamHandler; $logger = new Logger('name'); $logger->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); $translator = new Translator( new Resources( new Resource('*', 'de', [ 'Hello World' => 'Hallo Welt', ]), ), new Modifiers(), new MissingTranslationHandler($logger), // any PSR-3 logger ); var_dump($translator->trans('Hello World'));