PHP 8.4: Новые функции mb_ucfirst и mb_lcfirst
PHP предоставляет функции ucfirst и lcfirst для изменения верхнего или нижнего регистра первого символа в заданной строке.
Расширение mbstring предоставляет многобайтовые безопасные функции для большинства стандартных строковых функций PHP. Однако до версии PHP 8.4 расширение mbstring не предоставляло многобайтовых безопасных функций для функций ucfirst и lcfirst.
В PHP 8.4 расширение mbstring добавило функции mb_ucfirst и mb_lcfirst в качестве многобайтовых безопасных альтернатив функциям ucfirst и lcfirst.
Titlecase vs UPPERcase
Стандарт Unicode определяет список отображений символов, работающих по-разному в titlecase и uppercase.
Например, строчный символ nj (U+01CC — латинская строчная буква Nj) меняется на NJ (U+01CA — латинская заглавная буква Nj) в uppercase и на Nj (U+01CB — латинская заглавная буква N с маленькой буквой J) в titlecase. Другой пример — немецкий символ Eszett (ß — U+00DF), который в uppercase имеет вид SS, а в titlecase — Ss.
Смотрите Unicode FAQ и Derived Code Properties (Производные свойства кода Unicode) для кодовых точек со свойством Changes_When_Titlecased (CWT).
Новые функции mb_ucfirst и mb_lcfirst
Новые функции mb_ucfirst и mb_lcfirst предоставляют многобайтовые безопасные функции для изменения регистра первого символа на верхний или нижний регистр для заданной строки.
Как и остальные функции mb_*, функции mb_ucfirst и mb_lcfirst также принимают в качестве последнего параметра ?string $encoding = null, а первым параметром в обеих функциях является строка, регистр которой необходимо изменить.
Обратите внимание, что преобразования в многобайтовый регистр могут изменять как размер байта (вывод strlen()), так и длину (вывод mb_strlen()) значений. Например:
- Строчный символ знака Кельвина (
K—U+212A, занимает 3 байта) —k(U+006B, занимает 1 байт). - Символ Eszett (
ß) складывается вSs(titlecase) иSS(uppercase). Размер байта остаётся 2 байта, но в этом случае длина (mb_strlen()) меняется с 1 на 2.
Это может повлиять на функциональность, проверяющую длину и размер строки, например, ограничение размера индекса базы данных.
Функция mb_ucfirst
Функция mb_ucfirst преобразует первый символ заданной строки в titlecase. Остальная часть строки остаётся неизменной, даже если она находится в верхнем регистре. Разница с функцией 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
mb_ucfirst('TEST'); // TEST
mb_ucfirst('tEst'); // TEst
mb_ucfirst('tEst'); // TEst
mb_ucfirst('łámał'); // Łámał
mb_ucfirst("\u{01CA}"); // "\u{01CB}"
mb_ucfirst("💓🙈"); // "💓🙈" - без изменений
mb_ucfirst("ß"); // "Ss" - Только первая буква S в uppercase.Функция 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
mb_ucfirst('TEST'); // tEST
mb_ucfirst('tEst'); // tEst
mb_ucfirst('tEst'); // TEst
mb_ucfirst('Łámał'); // łámał
mb_ucfirst("\u{01CA}"); // "\u{01CB}"
mb_ucfirst("ß"); // "ß" - без измененийPHP полифиллы
Эти функции могут быть реализованы в PHP:
/**
* Переводит первый символ строки в верхний регистр в многобайтовом режиме.
*/
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);
}
/**
* Переводит первый символ строки в нижний регистр в многобайтовом режиме.
*/
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.
- PHP RFC: Multibyte for ucfirst, lcfirst functions, mb_ucfirst mb_lcfirst
- [VOTE][RFC] mb_ucfirst and mb_lcfirst functions
- Реализация