PHP 8.4: 新增 mb_ucfirst 和 mb_lcfirst 函数
PHP 提供 ucfirst
和 lcfirst
函数来更改给定字符串中第一个字符的大小写。
mbstring 扩展为 PHP 的大多数标准字符串函数提供了多字节安全函数。然而,在 PHP8.4 之前,mbstring 扩展没有为 ucfirst
和 lcfirst
函数提供多字节安全的对应函数。
在 PHP 8.4 中,mbstring 扩展添加了 mb_ucfirst
和 mb_lcfirst
函数,作为 ucfirst
和 lcfirst
函数的多字节安全替代方案。
Titlecase vs UPPERcase
Unicode 标准定义了一个字符映射列表,这些映射在 uppercase(大写)和 titlecase(标题大小写)中的工作方式不同。例如,小写字符
nj
(U+01CC
- 拉丁文小写字母 Nj)在大写中更改为NJ
(U+01CA
- 拉丁文大写字母 Nj);而 titlecase 中则改为Nj
(U+01CB
- 拉丁文大写字母 N 及小写字母 J)。另一个例子是德语 Eszett 字符(ß
-U+00DF
),其大写字母为SS
,而标题格为Ss
。有关具有
Changes_When_Titlecased
(CWT
) 属性的代码点,请参阅 Unicode 常见问题解答和 Unicode 派生代码属性。
新增 mb_ucfirst
和 mb_lcfirst
函数
新增的 mb_ucfirst
和 mb_lcfirst
函数提供了多字节安全函数,用以修改给定字符串的首字母大小写。
类似于其他的 mb_*
函数,mb_ucfirst
和 mb_lcfirst
函数也接受 ?string $encoding = null
作为最后一个参数,而这两个函数的第一个参数是需要修改大小写的字符串。
请注意,多字节转换可以改变字节大小(
strlen()
输出)以及值的长度(mb_strlen()
输出)。比如
- K 字符(
K
-U+212A
,占用 3 字节) 的小写字母为k
(U+006B
,1 字节)。- Eszett 字符 (
ß
) 转换为Ss
(titlecase) 和SS
(uppercase)。字节大小保留为 2 个字节,不过本例中,长度(mb_strlen()
)变为 1 到 2 字节。这可能会影响验证字符串长度和大小的功能,例如数据库索引大小限制。
mb_ucfirst
{#mb_ucfirst} 函数
mb_ucfirst
函数将给定字符的首个字符改为大写。其他字符保持不变,即使它是大写形式。和 ucfirst
函数不同的是,mb_ucfirst
支持多字节字符,因此支持所有的 Unicode 大写规范。
/**
* Make a string's first character uppercase multi-byte safely.
**/
function mb_ucfirst(string $string, ?string $encoding = null): string {}
用例
mb_ucfirst('test'); // Test - unchanged
mb_ucfirst('TEST'); // TEST
mb_ucfirst('tEst'); // TEst
mb_ucfirst('tEst'); // TEst
mb_ucfirst('łámał'); // Łámał
mb_ucfirst("\u{01CA}"); // "\u{01CB}"
mb_ucfirst("💓🙈"); // "💓🙈" - unchanged
mb_ucfirst("ß"); // "Ss" - Only the first S uppercase.
mb_lcfirst
{#mb_lcfirst} 函数
类似于 mb_ucfirst
函数,mb_lcfirst
将给定字符串的首个字符转换成小写。不像 lcfirst
函数,mb_lbfirst
可用修改多字节字符。
/**
* Make a string's first character lowercase multi-byte safely.
**/
function mb_lcfirst(string $string, ?string $encoding = null): string {}
用例
mb_ucfirst('test'); // test - unchanged
mb_ucfirst('TEST'); // tEST
mb_ucfirst('tEst'); // tEst
mb_ucfirst('tEst'); // TEst
mb_ucfirst('Łámał'); // łámał
mb_ucfirst("\u{01CA}"); // "\u{01CB}"
mb_ucfirst("ß"); // "ß" - unchanged
PHP Polyfills
这些函数可以在用户空间 PHP 中简单地实现:
/**
* Make a string's first character uppercase multi-byte safely.
*/
function mb_ucfirst(string $string, ?string $encoding = null): string {
$firstChar = mb_substr($string, 0, 1, $encoding);
$firstChar = mb_convert_case($firstChar, MB_CASE_TITLE, $encoding);
return $firstChar . mb_substr($string, 1, null, $encoding);
}
/**
* Make a string's first character lowercase multi-byte safely.
*/
function mb_lcfirst(string $string, ?string $encoding = null): string {
$firstChar = mb_substr($string, 0, 1, $encoding);
$firstChar = mb_convert_case($firstChar, MB_CASE_LOWER, $encoding);
return $firstChar . mb_substr($string, 1, null, $encoding);
}
以上实现也可以作为 Composer 包安装:
composer require polyfills/mb-ucfirst-lcfirst
向后兼容性影响
这两个函数,mb_ucfirst
和 mb_lcfirst
,在全局命名空间中声明。除非现有的函数在全局命名空间中使用了相同的名称,否则这个修改对向后兼容性不会有影响。
此外,新函数可以在用户空间 PHP 中实现。