3、PHP 8.4 新特性 - grapheme_str_split 函数
PHP 8.4 引入了 grapheme_str_split
函数,它主要用于按 可视字符(graphemes) 来分割字符串,而不是传统的字符。这个新函数的引入解决了在处理 Unicode 字符时的一个常见问题,即 Unicode 字符可能由多个字节组成,而普通的 str_split()
或 mb_str_split()
无法正确处理这种情况。
背景
在字符串处理中,有时我们需要分割字符,而不是字节。例如,Emoji 或带重音符的字符(如 é
)可能会由多个字节表示,但我们通常认为它们是一个字符。grapheme_str_split
可以按照可视字符来拆分字符串,不管它们由多少个字节组成。
函数签名
grapheme_str_split
函数与 mb_str_split
函数相似,支持指定一个整数参数 $length
来确定每个分块的长度。如果指定的长度大于整个字符串或某部分图符的长度,那么整个字符串或该部分将会被返回。
当传递一个空字符串时,grapheme_str_split
函数会返回一个空数组。
这个特性使得开发者可以根据需要灵活地分割字符串,特别是对于包含复杂脚本或表情符号的字符串,能够确保每个分块保持其图形单位的完整性,避免因为不当的分割而导致字符显示异常。
/**
* 将字符串拆分为图符的数组或图符块的数组。
*
* @param string $string 要拆分为单个图符或图符块的字符串。
* @param int $length 如果指定了此参数,返回数组中的每个元素将由多个图符组成,而不是单个图符。
*
* @return array|false 返回图符或图符块的数组,失败时返回 false。
*/
function grapheme_str_split(string $string, int $length = 1): array|false {}
grapheme_str_split 用法
案例一:基本用法
<?php
$string = 'hello 🌍';
$result = grapheme_str_split($string);
print_r($result);
输出
Array
(
[0] => h
[1] => e
[2] => l
[3] => l
[4] => o
[5] =>
[6] => 🌍
)
在这个例子中,字符串 "hello 🌍"
被正确分割成可视字符,每个字符作为数组的一个元素。注意 🌍
这个 Emoji 被作为一个单独的字符处理。
案例二:按长度分割
<?php
$string = "hello 🌍";
$result = grapheme_str_split($string, 2);
print_r($result);
输出
Array
(
[0] => he
[1] => ll
[2] => o
[3] => 🌍
)
案例三:对比 mb_str_split
<?php
$string = 'é අයේෂ්';
$mbResult = mb_str_split($string);
print_r($mbResult);
$graphemeResult = grapheme_str_split($string);
print_r($graphemeResult);
输出
Array
(
[0] => é
[1] =>
[2] => අ
[3] => ය
[4] => ේ
[5] => ෂ
[6] => ්
)
Array
(
[0] => é
[1] =>
[2] => අ
[3] => යේ
[4] => ෂ්
)
为什么需要 grapheme_str_split
?
在处理 Unicode 字符串时,单个字符(尤其是 Emoji 或带有组合字符的字符)可能由多个字节组成。传统的 str_split()
和 mb_str_split()
无法正确处理这种情况,因为它们依赖于字符的字节数进行分割,而不是字符本身的视觉单位(graphemes)。
例如,字符 é
是一个可视字符,但它可能由两个字节组成。grapheme_str_split
会正确地将其当作一个单独的字符,而不是分割成两个字节。
向后兼容性影响
新的 grapheme_str_split
函数是在 Intl 扩展中新引入的,并且声明在全局命名空间中。除非已经存在一个同名的函数,否则这一变更不应该引入任何向后兼容性问题。