Signature
mb_convert_case(string $string, int $mode, ?string $encoding = null): stringPurpose
mb_convert_case() changes the case of a string using Unicode character properties. Unlike strtolower() and strtoupper(), it understands multibyte text, so letters such as é, ä or Greek characters are converted properly. One function covers several conversions, selected by a mode constant: upper, lower, title and case folding, each with a full and a "simple" variant.
The manual notes that this function works from Unicode properties, so locale settings do not affect it. That makes results more predictable than the single-byte functions.
Signature
Parameters and defaults
$string: the text to convert.$mode: one ofMB_CASE_UPPER,MB_CASE_LOWER,MB_CASE_TITLE,MB_CASE_FOLD,MB_CASE_UPPER_SIMPLE,MB_CASE_LOWER_SIMPLE,MB_CASE_TITLE_SIMPLEorMB_CASE_FOLD_SIMPLE. There is no default; you must pass a mode.$encoding: the character encoding of the input. It defaults tonull, which means the internal encoding configured for the mbstring extension is used. Passing"UTF-8"explicitly makes your code independent of that setting.
Return value and failure cases
The function returns the converted string. If $encoding is not a valid encoding name, PHP 8 throws a ValueError. Before PHP 8.0.0 this produced a warning instead, so older code that checked for a false return no longer applies on PHP 8.4.
The manual's changelog adds that the simple and folding modes were added in PHP 7.3.0, and that in PHP 8.3.0 the conditional casing rules for the Greek letter sigma were implemented. They apply only to MB_CASE_LOWER and MB_CASE_TITLE, not to the _SIMPLE variants.
Example 1: upper and title case
Title mode capitalizes the first letter of each word and lowercases the rest, so mixed input comes out consistent.
$text = "mary had a Little lamb";
echo mb_convert_case($text, MB_CASE_UPPER, "UTF-8"), PHP_EOL;
echo mb_convert_case($text, MB_CASE_TITLE, "UTF-8"), PHP_EOL;MARY HAD A LITTLE LAMB Mary Had A Little Lamb
Example 2: non-ASCII text and case folding
Title mode handles accented letters. Full upper-casing can change the length of a string: the German ß becomes SS. Folding produces a form meant for case-insensitive comparison, so Straße folds to strasse.
$result = [
"title" => mb_convert_case("éCOLE nORMALE", MB_CASE_TITLE, "UTF-8"),
"upper" => mb_convert_case("Straße", MB_CASE_UPPER, "UTF-8"),
"fold" => mb_convert_case("Straße", MB_CASE_FOLD, "UTF-8"),
];
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"title":"École Normale","upper":"STRASSE","fold":"strasse"}
Example 3: an invalid encoding
Because PHP 8 throws on an unknown encoding name, you can catch the error when the encoding comes from configuration or user input.
try {
mb_convert_case("abc", MB_CASE_UPPER, "not-an-encoding");
} catch (ValueError $e) {
echo get_class($e), PHP_EOL;
}ValueError
Edge cases
- Length can change. Full modes may turn one character into several, as with
ßbecomingSS. Do not assume the result has the same number of characters as the input. - Full versus simple modes. The
_SIMPLEmodes use one-to-one character mappings, while the full modes can apply special multi-character rules. Choose the simple variants when you need a conversion that keeps the character count. - Title case is not a grammar tool.
MB_CASE_TITLElowercases the rest of each word. Acronyms such asNASAbecomeNasa, and it does not know which small words an editor would leave lowercase. Test names containing apostrophes or hyphens against your own expectations before relying on them. - Folding is for comparing.
MB_CASE_FOLDoutput is intended for matching, not for showing to users. - Empty strings are returned unchanged as empty strings.
Common mistakes
- Using
strtoupper()on UTF-8 text. The single-byte functions are not designed for multibyte characters, so accented text may not convert as you expect. - Relying on the internal encoding. If
$encodingis omitted, the result depends on the mbstring configuration. Pass"UTF-8"when your data is UTF-8. - Forgetting the mode argument. Unlike many PHP parameters,
$modeis required. - Checking for
false. Modern PHP throws aValueErrorrather than returningfalsefor a bad encoding. - Comparing display-cased strings. To compare text without regard to case, convert both sides with the same fold mode rather than comparing title-cased output.
- Feeding it invalid bytes. Strings that are not valid in the declared encoding can give unexpected output. Validate or convert input first.
Related functions
mb_strtolower()andmb_strtoupper()are shorter forms for plain lower and upper conversion.strtolower()andstrtoupper()are the single-byte counterparts.ucfirst()anducwords()capitalize the first character of a string or of each word, but they are not multibyte aware.
Recap
Use mb_convert_case() when you need Unicode-aware casing with a choice of modes. Pass the encoding explicitly, choose a simple mode when the character count must stay the same, use folding for comparisons, and catch ValueError when the encoding name is not trusted.
Tested examples
$text = "mary had a Little lamb";
echo mb_convert_case($text, MB_CASE_UPPER, "UTF-8"), PHP_EOL;
echo mb_convert_case($text, MB_CASE_TITLE, "UTF-8"), PHP_EOL;
MARY HAD A LITTLE LAMB Mary Had A Little Lamb
$result = [
"title" => mb_convert_case("éCOLE nORMALE", MB_CASE_TITLE, "UTF-8"),
"upper" => mb_convert_case("Straße", MB_CASE_UPPER, "UTF-8"),
"fold" => mb_convert_case("Straße", MB_CASE_FOLD, "UTF-8"),
];
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
{"title":"École Normale","upper":"STRASSE","fold":"strasse"}
try {
mb_convert_case("abc", MB_CASE_UPPER, "not-an-encoding");
} catch (ValueError $e) {
echo get_class($e), PHP_EOL;
}
ValueError