PHP 8.4: MBString: Unicode 字符数据库更新到版本 16
MBString 扩展包含从 Unicode 规范中提取的数据子集,用于其操作,比如将给定字符串转换为大写或小写,确定给定字符串的宽度(在某些东亚脚本中有用)等。
在 PHP 8.3 中,MBString 扩展包含了 2022 年 9 月发布的 Unicode 14.0 标准的数据。在 PHP 8.4 中,Unicode 字符数据库(UCD)数据源从 14.0 更新到2024 年 9 月发布的 16.0。Unicode 16.0 是当时发布的最新 UCD。
Unicode 15.0、15.1 和 16.0 增加了 4489、627 和 5185 个新字符。此外,这三个 Unicode 版本合起来还支持另外 11 个脚本。然而,对于 MBString 扩展,重要的更新是字符大小写折叠规则,这些规则会影响函数,如 mb_strtolower
、mb_strtoupper
和东亚宽度值分配,这些值分配决定了给定字符是被视为正常宽度还是宽度(mb_strwidth
)。
随着对 Unicode 16 支持的引入,MBString 扩展可以处理所有最新的 Emoji 表情符号字符,并具有最新的大小写折叠和字符宽度信息。
MBString 函数没有任何直接更改。Unicode 字符数据是 MBString 扩展本身的一部分,将在所有 PHP 8.4 函数中使用。
向后兼容性影响
UCD 16 目前是 Unicode 标准的最新版本,由于任何函数参数和返回值都没有变化,这不太可能导致任何向后兼容性问题。
但是,请注意,在 PHP 8.4 及更高版本中,以前在旧 PHP 版本上进行过大小写转换或宽度测量的数据返回不同数据还是有小概率。
其中一些例子包括:
echo "Emoji: \u{1F6DC}, width: " . mb_strwidth("\u{1F6DC}");
// Emoji: 🛜, width: 2
WiFi 表情符 (🛜) 在 UCD 15 中添加,旧版的 PHP 不能识别 1F6DC
码点,将返回 width: 1
。
echo mb_strtoupper("\u{019b}") === "\u{a7dc}";
在 UCD 16中,019b
字符有一个新的大小写映射(ƛ - 拉丁小写字母 Lambda 加上中横线)。PHP 8.3 和旧版本不支持这种大小写映射,因此mb_strtoupper("\u{019b}")
返回 "\u{019b}"
本身。在 PHP 8.4 及更高版本的 UCD 16 中, mb_strtoupper("\u{019b}")
返回 "\u{a7dc}"
。
Parity with other functionality
Intl 扩展和 PCRE 扩展在其操作中也使用 Unicode 字符数据库。
在PHP 8.4 中,PCRE2 库更新为 10.44。PCRE2 是用 UCD 15 构建的。
Intl 扩展依赖于 ICU 库的 Unicode 数据表。在默认构建中,底层 ICU 库的 UCD 版本可能是 UCD 15。
虽然低概率,但 MBString、Intl 和 PCRE 扩展中可能存在处理字符不同的边缘情况。例如,PCRE 扩展无法将 Unicode 16 中 "\u{019b}"
字符的新大写映射识别为大写字符:
preg_match('/\p{Ll}/u', "\u{019b}"); // Unicode aware, match any lowercase character
// Matches in PHP 8.3 and 8.4.
preg_match('/\p{Lu}/u', mb_strtoupper("\u{019b}")); // Unicode aware, match any uppercase character
// Does not match in any PHP 8.3 or 8.4, although it is considered an uppercase character.
请注意,UCD 版本号不匹配在 PHP 8.4 中并不新鲜,UCD 不匹配导致问题的可能性很小。