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
- Реализация