m1sh0u/polyglot-php

Polyglot.php 是 Airbnb 的 Polyglot.js I18n 辅助库的副本

v1.3 2022-07-26 09:16 UTC

This package is auto-updated.

Last update: 2024-09-26 13:58:41 UTC


README

Latest Version on Packagist Software License Tests Code Quality Total Downloads

Polyglot.php 是一个用 PHP 编写的轻量级 I18n 辅助库,它完全基于 Airbnb 的 Polyglot.js I18n JavaScript 库。

复制 Airbnb 的 JavaScript 库的决定是为了拥有一个小巧但功能强大的库,让开发者能够以与前端应用程序相同的方式国际化他们的 PHP 后端。

Polylglot 不执行任何翻译;它只是提供了一个管理从服务器端 PHP 应用程序翻译短语的方式。

安装

使用 composer 安装

$ composer require m1sh0u/polyglot-php

运行测试

克隆仓库,运行 composer update --prefer-dist --dev,然后运行 composer test,或者 Windows 上的 composer test-win

用法

实例化

首先,创建一个 Polyglot 类的实例,您将使用它进行翻译。

$polyglot = new Polyglot();

Polyglot 是基于类的,因此您可以在同一时间维护不同集合的短语,可能在不同区域设置中。

有关您可以传递给 new Polyglot 的选项数组的信息,请参阅 选项概述

翻译

通过简单地提供一个短语键值对,告诉 Polyglot 要说什么,其中键是短语的规范名称,值是已翻译的字符串。

$polyglot->extend([
  "hello" => "Hello"
]);

$polyglot->t("hello");
=> "Hello"

您也可以在实例化时传递一个映射,使用键 phrases

$polyglot = new Polyglot(['phrases' => ["hello" => "Hello"]]);

Polyglot 不会为您执行翻译。您需要提供用户区域设置的适当短语。

插值

Polyglot->t() 还提供了插值。将包含插值参数键值对的数组作为第二个参数传递。

$polyglot->extend([
  "hello_name" => "Hola, %{name}."
]);

$polyglot->t("hello_name", ["name" => "DeNiro"]);
=> "Hola, DeNiro."

Polyglot 也支持嵌套短语对象。

$polyglot->extend([
  "nav" => [
    "hello" => "Hello",
    "hello_name" => "Hello, %{name}",
    "sidebar" => [
      "welcome" => "Welcome"
    ]
  ]
]);

$polyglot->t("nav.sidebar.welcome");
=> "Welcome"

替换变量语法是可定制的。

$polyglot = new Polyglot({
  "phrases" => [
    "hello_name" => "Hola {{name}}"
  ],
  "interpolation" => ["prefix" => "{{", "suffix" => "}}"]
});

$polyglot->t("hello_name", ["name" => "DeNiro"]);
=> "Hola, DeNiro."

复数化

为了正确执行复数化,您需要告诉 Polyglot 当前的区域设置。您可以使用 $polyglot->locale("fr") 将区域设置设置为,例如,法语。此方法也是获取器

$polyglot->locale()
=> "fr"

您也可以在实例化时传递此内容。

$polyglot = new Polyglot(["locale" => "fr"]);

目前,Polyglot 使用此区域设置设置的唯一方法是复数化。

Polyglot 提供了一个非常基本的模式,用于根据包含给定短语所有复数形式的单个字符串提供复数化。

要获取复数化短语,仍然使用 $polyglot->t(),但使用特别格式化的短语字符串,该字符串通过分隔符 ||||(或四个垂直管道字符)分隔复数形式。

对于英语中的 "car" 复数化,Polyglot 假设您有一个以下形式的短语

$polyglot->extend([
  "num_cars" => "%{smart_count} car |||| %{smart_count} cars",
]);

在英语(以及德语、西班牙语、意大利语和少数其他语言)中,只有两种复数形式:单数和复数。

有些语言要复杂一些。在捷克语中,有三种不同的形式:1、2 到 4 以及 5 以上。俄语则更加复杂。

$polyglot = new Polyglot(["locale" => "cs"]); // Czech
$polyglot->extend([
  "num_foxes" => "Mám %{smart_count} lišku |||| Mám %{smart_count} lišky |||| Mám %{smart_count} lišek"
])

$polyglot->t() 将根据提供的 smart_count 选项选择适当的短语,其值是一个数字。

$polyglot->t("num_cars", ["smart_count" => 0]);
=> "0 cars"

$polyglot->t("num_cars", ["smart_count" => 1]);
=> "1 car"

$polyglot->t("num_cars", ["smart_count" => 2]);
=> "2 cars"

作为一个快捷方式,您也可以将数字传递给第二个参数

$polyglot->t("num_cars", 2);
=> "2 cars"

自定义复数规则

如果需要,可以为特定区域替换现有的复数规则或指定新的自定义复数规则。自定义复数规则必须是实现 Polyglot\Pluralization\Rules\RuleInterface 的对象。它们将被作为键值对传递给 Polyglot 的 pluralRules 选项,其中键是区域,值是自定义规则对象。

让我们为罗马尼亚语定义一个自定义复数规则

use Polyglot\Pluralization\Rules\RuleInterface;

class RomanianRule implements RuleInterface
{
    public function decide(int $n): int
    {
        return $n !== 1 ? 1 : 0;
    }
}

现在您可以将它传递给 Polyglot 选项,以便在需要复数时使用 ro 区域

$polyglot = new Polyglot([
    'phrases' => ['num_cars' => '%{smart_count} mașină |||| %{smart_count} mașini'],
    'locale' => 'ro',
    'pluralRules' => ['ro' => new RomanianRule()]
]);

$polyglot->t('num_cars', 1)
=> 1 mașină
$polyglot->t('num_cars', 6)
=> 6 mașini

公共实例方法

Polyglot->t($key, $interpolationOptions)

最常用的方法。提供一个键,t() 将返回短语。

$polyglot->t("hello");
=> "Hello"

短语值首先由对 $polyglot->extend()$polyglot->replace() 的调用提供。

将一个对象作为第二个参数传递以执行插值。

$polyglot->t("hello_name", ["name" => "Spike"]);
=> "Hello, Spike"

将一个数字作为第二个参数传递,作为 smart_count 的快捷方式

// same as: $polyglot->t("car", ["smart_count" => 2]);
$polyglot->t("car", 2);
=> "2 cars"

如果您愿意,可以在短语缺失时提供一个默认值。使用特殊选项键 "_" 来指定默认值。

$polyglot->t("i_like_to_write_in_language", [
  "_" => "I like to write in %{language}.",
  "language" => "JavaScript"
]);
=> "I like to write in JavaScript."

Polyglot->extend($phrases)

使用 extend 来告诉 Polyglot 如何翻译给定的键。

$polyglot->extend([
  "hello" => "Hello",
  "hello_name" => "Hello, %{name}"
]);

键可以是任何字符串。您可以根据需要多次调用 extend;它将覆盖具有相同键的任何短语,但不会更改现有的短语。

Polyglot->unset($keyOrArray)

使用 unset 来选择性地从 Polyglot 实例中删除键。 unset 接受一个参数:一个单个的字符串键,或者一个键是字符串键的数组,其值被忽略,除非它们是嵌套数组(具有相同的格式)。

示例

$polyglot->unset('some_key');
$polyglot->unset([
  'hello' => 'Hello',
  'hello_name' => 'Hello, %{name}',
  'foo' => [
    'bar' => 'This phrase’s key is "foo.bar"'
  ]
]);

Polyglot->locale(?$localeToSet)

获取或设置区域(也可以使用 构造函数选项 设置,它仅用于复数化。如果提供了真值,它将设置区域。之后,它将返回它。

Polyglot->clear()

清除所有短语。在特殊情况下很有用,例如,如果您有很多短语但不再需要执行任何翻译,则可用于释放内存。也由 replace 内部使用。

Polyglot->replace($phrases)

完全用一组新的短语替换现有的短语。通常,只需使用 extend 添加更多短语,但在某些情况下,您可能想确保没有旧短语留下。

Polyglot->has($key)

如果提供的短语中存在该键,则返回 true,否则返回 false

Polyglot->phrases()

返回所有短语。

Polyglot->transformPhrase($phrase[, $substitutions[, $locale[, $tokenRegex]]])

  • 接受一个短语字符串,通过选择正确的复数形式并插值来对其进行转换。此方法由 t 内部使用。
  • 如果设置了 $substitutions['smart_count'],则选择正确的复数形式。
  • 您可以将数字而不是数组作为 $substitutions 传递,作为 smart_count 的快捷方式。
  • 您应该传递第三个参数,即区域,以指定正确的复数类型。默认为 'en',它有 2 个复数形式。
  • 您应该传递第四个参数,以指定插值令牌正则表达式。默认为 ~%{(.*?)}~。注意:默认情况下包含正则表达式分隔符 ~

选项概述

new Polyglot 接受一些选项

  • phrases: 已翻译短语的键/值映射。
  • locale: 描述翻译的区域(语言和地区)的字符串,用于应用复数规则。参见 复数化
  • delimiter: 用于复数化的分隔符。默认分隔符是 ||||。参见 复数化
  • allowMissing: 一个布尔值,用于控制在 t 调用中是否允许缺失的键。默认情况下,如果 false,则返回缺失的键并发出警告。
  • onMissingKey:如果 allowMissing 设置为 true,并且此选项是一个函数,那么将调用该函数而不是默认功能。传递给它的参数包括 $key$options$locale$tokenRegexPolyglot $polyglot。此函数的返回值将在调用 $polyglot->t('missing.key') 时用作翻译回退(提示:返回键)。
  • interpolation:一个数组,用于通过设置 prefixsuffix 字段来更改插值语法。
  • pluralRules:通过提供一个键值对来替换或为特定区域设置添加新的复数规则,其中键是区域设置,值是实现 Polyglot\Pluralization\Rules\RuleInterface 的复数规则对象。

相关项目

  • Polyglot.js:Polyglot.js 是一个用 JavaScript 编写的轻量级 I18n 辅助库,旨在在浏览器和 CommonJS 环境中(Node)工作。它提供了一个简单的解决方案,用于插值和复数化,基于 Airbnb 在其 Backbone.js 和 Node 应用中添加 I18n 功能的经验。