mb_strtolower
Converts all alphabetic characters in a string to lowercase using Unicode case rules.
mb_strtolower(string $string, ?string $encoding = null): string- Added in PHP 4.3.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | The string being lowercased. |
$encodingoptional | ?string= null | Character encoding of the string. Falls back to the internal encoding when null. |
Return value
stringThe string with every character that has the Unicode 'alphabetic' property converted to lowercase.
Errors
Throws a ValueError if encoding names an unknown character encoding.
Changelog
- PHP 8.3.0Implemented conditional casing rules for the Greek letter sigma, so a final Σ now lowercases to ς instead of σ.
mb_strtolower() lowercases every character that Unicode marks as alphabetic, not just A–Z. That means Ä becomes ä, Ω becomes ω and Ж becomes ж. Plain strtolower() has been ASCII-only since PHP 8.2, so it silently leaves every accented letter untouched.
When to reach for it
Reach for it whenever you normalise text for comparison: search keys, tag slugs, deduplication buckets, cache keys, case-insensitive lookups against user input. If any of that data can contain non-English text — and it usually can — the ASCII function will treat Über and über as different strings and your lookup will miss.
What trips people up
Case folding here is locale-independent. It follows Unicode character properties, not the user's language, so it cannot do Turkish dotless-i: mb_strtolower('I') gives i, never ı. Since PHP 8.3 Greek sigma is context-sensitive, so a word-final Σ correctly becomes ς.
Lowercasing is also not the same as case folding for comparison. German ß stays ß, but uppercasing it produces SS, so mb_strtolower(mb_strtoupper('ß')) returns ss — a round trip that does not come back to where it started.
Example
When to use it
- Normalise a user's search query and the indexed text before comparing them.
- Build a lowercase slug or cache key from a title containing accented characters.
- Deduplicate a list of email addresses or tags that differ only by capitalisation.
- Compare two names case-insensitively without losing German, Greek or Cyrillic characters.
Frequently asked questions
What is the difference between strtolower and mb_strtolower?
strtolower only converts the ASCII letters A–Z and leaves accented or non-Latin characters unchanged, while mb_strtolower uses Unicode properties and lowercases them all. Since PHP 8.2 strtolower ignores locale entirely, so it will never handle ü, Ω or Ж.
Does mb_strtolower handle Turkish I correctly?
No. Case conversion is based on Unicode character properties and is not locale-aware, so mb_strtolower('I') always returns 'i', never the Turkish dotless 'ı'. Use the intl extension if you need locale-specific casing.
Should I use mb_strtolower or mb_convert_case for comparisons?
For comparison keys prefer mb_convert_case($s, MB_CASE_FOLD), which applies full Unicode case folding and maps ß to ss. mb_strtolower is the right choice when you want text that will actually be displayed.
More examples
Case-insensitive matching that survives accents
Both "Hauptstraße 4" and "STRAßENBAHN" match because mb_strtolower folds them to the same characters as the query. "Bahnhofstrasse 9" does not match: lowercasing never converts ss into ß, so spelling variants still need a separate normalisation step.
<?php
$query = mb_strtolower("STRAßE");
$rows = ["Hauptstraße 4", "Bahnhofstrasse 9", "STRAßENBAHN"];
foreach ($rows as $row) {
$hit = str_contains(mb_strtolower($row), $query) ? "match" : "-";
echo $row, " => ", $hit, "\n";
}The Greek final sigma rule
Since PHP 8.3, a sigma at the end of a word lowercases to ς while sigmas inside a word stay σ, so "ΟΔΥΣΣΕΥΣ" becomes "οδυσσευς" with a final ς. mb_convert_case with MB_CASE_LOWER applies the same conditional rule, which is why the comparison is true.
<?php
echo mb_strtolower("ΟΔΥΣΣΕΥΣ"), "\n";
echo mb_strtolower("ΣΟΦΟΣ ΑΝΗΡ"), "\n";
var_dump(mb_strtolower("ΟΔΥΣΣΕΥΣ") === mb_convert_case("ΟΔΥΣΣΕΥΣ", MB_CASE_LOWER));
Discussion