34、PHP 8.4 方法或功能修改 - MBString:Unicode 字符数据库已更新到版本 16

作者: 温新

图书: 【PHP 8.4 新特性】

阅读: 95

时间: 2025-01-17 17:28:35

PHP 8.4 中,MBString(Multibyte String)扩展引入了一项重要更新:Unicode 字符数据库已更新至版本 16。这意味着,MBString 现在支持最新的 Unicode 字符集和规范,确保了对更广泛的字符集、符号和表情符号(emoji)的支持。

Unicode 15.0、15.1 和 16.0 分别增加了 4,489、627 和 5,185 个新字符。此外,这三个 Unicode 版本的更新还支持了 11 种新的书写系统。然而,对于 MBString 扩展来说,重要的更新是在字符大小写折叠规则方面,这影响到像 mb_strtolowermb_strtoupper 这样的函数,以及东亚宽度值的分配,用于确定给定字符是被视为标准宽度还是宽字符(mb_strwidth)。

通过对 Unicode 16 的支持,MBString 扩展能够处理所有最新的 Emoji 字符,并且具备最为更新的大小写折叠和字符宽度信息。

MBString 函数本身没有直接的变化。Unicode 字符数据是 MBString 扩展的一部分,将在所有 PHP 8.4 的函数中使用。

如何使用 MBString 处理 Unicode 字符

<?php
$str = "Hello, 👋🌍!";
echo mb_strlen($str, 'UTF-8'); // 正确处理表情符号

向后兼容性影响

UCD 16 当前是 Unicode 标准的最新版本,由于函数参数和返回值没有发生变化,因此不太可能引起任何向后兼容性问题。

然而,请注意,之前在旧版 PHP 中进行过大小写转换或宽度测量的数据,在 PHP 8.4 及以后的版本中可能会返回不同的数据。

以下是一些示例:

echo "Emoji: \u{1F6DC}, width: " . mb_strwidth("\u{1F6DC}");
// 输出: Emoji: 🛜, width: 2

WiFi 表情符号(🛜)是在 UCD 15 中添加的,旧版 PHP 无法识别 1F6DC 代码点,因此返回宽度为 1。

echo mb_strtoupper("\u{019b}") === "\u{a7dc}";

在 UCD 16 中,019b 字符(ƛ - 拉丁小写字母 Lambda 带横杠)有了新的大小写映射。PHP 8.3 及更早版本不支持这个大小写映射,因此 mb_strtoupper("\u{019b}") 会返回 "\u{019b}" 本身。而在 PHP 8.4 及以后版本中,mb_strtoupper("\u{019b}") 会返回 "\u{a7dc}"

上述代码片段使用了十六进制 Unicode 字符转义符,并放在双引号字符串中。

与其他功能的对比

Intl 扩展和 PCRE 扩展也在其操作中使用了 Unicode 字符数据库。

在 PHP 8.4 中,PCRE2 库更新到了 10.44,且 PCRE2 是基于 UCD 15 构建的。

Intl 扩展依赖于 ICU 库来提供 Unicode 数据表。在默认构建下,底层 ICU 库的 UCD 版本通常是 UCD 15。

尽管不太可能,但在 MBString、Intl 和 PCRE 扩展中处理字符时可能会出现边缘情况。例如,Unicode 16 中对 \u{019b} 字符的新大小写映射在 PCRE 扩展中没有被识别为大写字符:

preg_match('/\p{Ll}/u', "\u{019b}"); // Unicode 识别,匹配任何小写字符
// 在 PHP 8.3 和 8.4 中都能匹配

preg_match('/\p{Lu}/u', mb_strtoupper("\u{019b}")); // Unicode 识别,匹配任何大写字符
// 在 PHP 8.3 或 8.4 中都不会匹配,尽管它被认为是大写字符

请注意,UCD 版本号不匹配的问题在 PHP 8.4 中并不新鲜,UCD 不匹配导致问题的可能性是非常低的。

请登录后再评论