Case, Trimming and Wrapping

strtoupper(), ucfirst(), ucwords() and their kin change ASCII letters only, and since PHP 8.2 ignore the locale. Text needs mb_strtoupper(), mb_convert_case() and PHP 8.4's mb_ucfirst(). trim() strips ASCII whitespace or a character list (a..z is a range); PHP 8.4's mb_trim(), mb_ltrim() and mb_rtrim() also remove Unicode spaces and take multibyte lists.

ASCII versus multibyte case and trimming (case.php)PHP
<?php
echo strtoupper('php é'), ' | ', ucwords("mary-jane o'neil", " -'"), ' | ',
    ucfirst('élan'), ' | ', mb_ucfirst('élan'), ' | ', mb_strtoupper('straße'), "\n";
echo '[', trim("  \t padded \n"), '] [', rtrim('1.500', '0'), '] [',
    trim('--==title==--', '-='), '] [', trim('abcHELLOxyz', 'a..z'), "]\n";
$city = "\u{3000}Tokyo\u{00A0}";                  // ideographic and no-break spaces
echo '[', trim($city), '] [', mb_trim($city), '] [', mb_rtrim('★Hi★★', '★'), "]\n";
echo wordwrap('PHP 8.5 adds the pipe operator.', 20, "\n", true), "\n";
Output
PHP é | Mary-Jane O'Neil | élan | Élan | STRASSE
[padded] [1.5] [title] [HELLO]
[ Tokyo ] [Tokyo] [★Hi]
PHP 8.5 adds the
pipe operator.

ucwords() takes a delimiter list, so hyphenated and Irish names come out right. trim() missed the ideographic and no-break spaces that pasted text carries, so a field holding only a no-break space passes a trim($v) === '' check; validate with mb_trim(). wordwrap() counts bytes.