编程

PHP 8.5: Intl: 新增 IntlListFormatter 类

9 2025-10-23 23:35:00

PHP 8.5 中的 Intl 扩展添加了一个名为 IntlListFormatter 的新类。它为列表提供了区域(locale)感知的格式化,使其成为人类可读的“和”列表、“或”列表或单位列表。

新的 IntlListFormatter 类遵循与 Intl 扩展中的其他类相同的模式;它使用有效的 locale 字符串进行实例化,并使用 ICU 数据进行实际格式化。

$formatter = new IntlListFormatter('en-US');
$formatter->format(['Zurich', 'Berlin', 'Amsterdam']);
// Zurich, Berlin, and Amsterdam
$formatter = new IntlListFormatter('nl-NL');
echo $formatter->format(['Zurich', 'Berlin', 'Amsterdam']);
// Zurich, Berlin en Amsterdam
$formatter = new IntlListFormatter('id-ID');
echo $formatter->format(['Zurich', 'Berlin', 'Amsterdam']);
// Zurich, Berlin, dan Amsterdam

IntlListFormatter 类摘要

final class IntlListFormatter {

    public const int TYPE_AND = 0;
    public const int TYPE_OR = 1;
    public const int TYPE_UNITS = 3;

    public const int WIDTH_WIDE = 0;
    public const int WIDTH_SHORT = 1;
    public const int WIDTH_NARROW = 2;

    public function __construct(
        string $locale,
        int $type = IntlListFormatter::TYPE_AND,
        int $width = IntlListFormatter::WIDTH_WIDE
    ) {}

    public function format(array $strings): string|false {}

    public function getErrorCode(): int {}
    public function getErrorMessage(): string {}

}
  • 新增的 IntlListFormatter 类在全局命名空间中声明。
  • 它被声明称 final,因此不能被继承。

IntlListFormatter::TYPE_ 常量

实例化 IntlListFormatter 对象时,构造函数接收一个 $type 参数。默认情况下,该参数为 IntlListFormatter::TYPE_AND。此外,也可以使用以下这些值:

  • IntlListFormatter::TYPE_AND: 将列表分组成“和(and)"列表。e.g. X, Y, and Z
  • IntlListFormatter::TYPE_OR: 将列表分组成“或(or)"列表。. e.g. X, Y, or Z
  • IntlListFormatter::TYPE_UNITS: 将列表分组为复合单元,该单元不基于和/或。e.g. 4 hours, 30 minutes

IntlListFormatter::WIDTH_ 常量

IntlListFormatter 构造函数的第三个参数是 $width,它接受 IntlListFormatter::WIDTH_ 常量。默认值是 IntlListFormatter::WIDTH_WIDE.

该参数用来控制该列表的宽窄程度。可能需要调整输入列表以与此保持一致。

  • IntlListFormatter::WIDTH_WIDE: 通常的列表格式化,e.g. X, Y, and Z
  • IntlListFormatter::WIDTH_SHORT: 尝试让列表更短。如果语言中有较短的“和”/“或”单词或符号,则将使用它。e.g. A, B & C
  • IntlListFormatter::WIDTH_NARROW: 如果区域设置有,请使用尽可能窄的方式格式化列表。它也经常省略“和”这个词。 e.g. A, B, C.

并非所有语言都有不同的简短形式。如下面的  de-DE 示例所示,如果区域语言不区分所有宽度,它们可能会产生相同的输出。

用例

en-US 的格式化列表

en-USTYPE_ANDTYPE_ORTYPE_UNITS
WIDTH_WIDEA, B, and CA, B, or CA, B, C
WIDTH_SHORTA, B, & CA, B, or CA, B, C
WIDTH_NARROWA, B, CA, B, or CA B C

ja-JP 的格式化列表

ja-JPTYPE_ANDTYPE_ORTYPE_UNITS
WIDTH_WIDE水、火、木水、火、または木水 火 木
WIDTH_SHORT水、火、木水、火、または木水 火 木
WIDTH_NARROW水、火、木水、火、または木水火木

de-DE 的格式化列表

de-DETYPE_ANDTYPE_ORTYPE_UNITS
WIDTH_WIDEA, B und CA, B oder CA, B und C
WIDTH_SHORTA, B und CA, B oder CA, B und C
WIDTH_NARROWA, B und CA, B oder CA, B und C

错误处理

如果 format 调用成功,getErrorCode 方法将返回 int(0),而 getErrorMessage 方法将返回 “U_ZERO_ERROR”

如果 IntlListFormatter::format 方法返回 false,则说明格式化时出现错误。这种情况下,getErrorCodegetErrorMessage 方法将能提供更多信息。

向后兼容性影响

IntlListFormatter PHP 类使用了 ICU 库的 icu::ListFormatter,它是 ICU 50 添加的。

PHP 8.5 的 Intl 扩展要求 ICU 57.1 及以上版本,因此,IntlListFormatter 类在所有的 Intl 扩展编译中都是可用的。

通过枚举 CLDR(Common Locale Data Repository) 中各种语言环境的格式规则,理论上可以用户空间 PHP 中对 IntlListFormatter 类进行 polyfill。然而,它需要提取和存储大多数(如果不是全部)地区的相关 CLDR 数据。

 

PHP