Title-case a string with Unicode support
Write a function capitalize that uppercases the first letter of every word in a string. It must work for non-Latin alphabets such as Cyrillic.
<?php
echo capitalize('hello avito'); // Hello Avito
echo capitalize('привет авито'); // Привет Авито
function capitalize(string $string) {
// your code here
}
Write the implementation.
Use mb_convert_case($string, MB_CASE_TITLE). The multibyte mb_* family is UTF-8 aware, so it uppercases the first letter of each word correctly for Cyrillic. The non-multibyte ucwords treats each byte as a character and corrupts multibyte letters, producing mojibake on привет.
- ✗Reaching for
ucwords/ucfirst, which operate on single bytes and break UTF-8 - ✗Assuming UTF-8 source encoding makes byte-based string functions Unicode-safe
- ✗Forgetting to set or pass the encoding, leaving
mb_*to guess the wrong charset
- →Why does
strlen('привет')return 12 rather than 6, and which function returns 6? - →How do you make
mb_*functions assume UTF-8 without passing the encoding each call?
Strings in PHP are sequences of bytes, not characters. A Latin letter is one byte in UTF-8, but a Cyrillic letter is two. So functions that operate byte-by-byte (strlen, ucwords, ucfirst, strtoupper) corrupt multibyte text.
<?php
function capitalize(string $string) {
return mb_convert_case($string, MB_CASE_TITLE);
}
echo capitalize('hello avito'); // Hello Avito
echo capitalize('привет авито'); // Привет Авито
mb_convert_case($s, MB_CASE_TITLE) understands word boundaries and Unicode casing. For safety set the default encoding with mb_internal_encoding('UTF-8') or pass it as the third argument.