编程

PHP 8.6: 新增 grapheme_strrev 函数

7 2026-06-18 06:08:00

Intl 扩展的 Grapheme 函数引入了一个新函数,叫做 grapheme_strrev,用于以字位单元作为反转字符串的顺序单位。

strrev 函数的区别在于,grapheme_strrev 是以“字素簇”(grapheme clusters)为单位进行操作的,而 strrev 则是以字节为单位对给定字符串进行反转。对于 ASCII 字符,strrevgrapheme_strrev 返回的结果完全一致;但对于包含多字节或多码点字符的字符串,grapheme_strrev 能够正常工作,因为它操作的单位是“字素”(grapheme,即书写系统中最小的功能单位)。

例如,以 Emoji 表情 👍🏽 为例:它是 Emoji 表情 👍 (U+1F44D) 与肤色修饰符 🏽 (U+1F3FD) 的组合。

strrev 函数会破坏这个 Emoji 的结构,因为它操作的是单个字节。
虽然目前没有名为 mb_strrev 的函数,但即使是支持多字节处理的反转函数,也会破坏这种结构,因为该 Emoji 是由两个多字节码点拼接而成的:A👍🏽C -> C 🏽👍A。
只有 grapheme_strrev 函数能正确地将字素簇作为一个整体单位进行反转,从而将 A👍🏽C 反转为 C👍🏽A,生成可读的文本。

新增的 grapheme_strrev 函数

/**
 * Reverse a string by grapheme clusters.
 * @param string $string The string to reverse
 * @return string|false The reversed string, or false on failure
 */
function grapheme_strrev(string $string): string|false;

该函数声明于全局命名空间中。
该字符串可能包含 NUL 字符,这些字符也将包含在反转后的字符串中。

使用示例

grapheme_strrev('ABCDE'); // EDCBA
grapheme_strrev('Apple🍏'); // 🍏elppA
grapheme_strrev('🇨🇳 - 🇳🇨'); // 🇳🇨 - 🇨🇳

向后兼容性影响

grapheme_strrev 是一个在全局命名空间中声明的新函数。除非 PHP 应用在全局命名空间中声明了同名函数,否则此更改不会破坏现有的应用。

在 PHP 8.4 及更高版本中,可以在用户空间对该函数进行 Polyfill(兼容性填充):

function grapheme_strrev(string $string): string|false {
    $units = grapheme_str_split($string);
    if ($units === false) {
        return false;
    }

    return implode('', array_reverse($units));
}

上述 Polyfill 方案使用了 PHP 8.4 中新增的 grapheme_str_split 函数。反过来,我们也可以利用正则表达式 \Xgrapheme_str_split 函数本身提供 Polyfill。但这要求 PCRE 版本不低于 10.43;对于较旧的 PHP 版本而言,除非在编译时指定了自定义的 PCRE 版本,否则通常不会包含这一要求。