strtolower

Converts all ASCII uppercase letters in a string to lowercase.

Signature
strtolower(string $string): string
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$stringstringThe input string.

Return value

stringThe input string with every ASCII character in the range A–Z converted to its lowercase equivalent.

Changelog

  • PHP 8.2.0Case conversion no longer depends on the locale set with setlocale(). Only ASCII characters A–Z are converted.

strtolower does nothing more than add 32 to every byte between A (0x41) and Z (0x5A) and leaves everything else untouched. It is binary-safe and it is fast, because it is a pure byte operation with no encoding awareness at all.

When to reach for it

Use it for normalising values that are ASCII by definition: HTTP header names, file extensions, protocol schemes, enum-style keys, or the local part of an identifier before comparing it. Lowercasing both sides of a comparison is a common idiom, though strcasecmp does the same job in one call without allocating new strings.

What trips people up

Since PHP 8.2 this function is locale-independent and ASCII-only, which is a good thing but changes old behaviour: É, Ä, Ş and every other non-ASCII letter pass straight through unchanged. Code that relied on setlocale(LC_CTYPE, 'de_DE') to fold accented letters no longer works.

For user-facing text in any encoding beyond ASCII, use mb_strtolower($s, 'UTF-8'). And remember that lowercasing is not the same as case-folding for security decisions — do not use it to compare passwords or to decide that two Unicode identifiers are the same.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Normalise an HTTP header name or a file extension before looking it up in a map.
  • Build a case-insensitive lookup key for an array of ASCII identifiers.
  • Lowercase the domain half of an email address, which is case-insensitive by spec, while leaving the local part alone.

Frequently asked questions

Why does strtolower not work on accented characters?

Since PHP 8.2 it converts only the ASCII range A–Z and ignores the locale, so bytes above 0x7F are left untouched. Use mb_strtolower($string, 'UTF-8') for accented or non-Latin text.

What is the difference between strtolower and mb_strtolower?

strtolower is a byte operation limited to ASCII, while mb_strtolower understands a character encoding and lowercases the full Unicode range. mb_strtolower is slower but correct for UTF-8 text.

Is strtolower safe on UTF-8 strings?

Yes, it will not corrupt them — multibyte sequences are simply left alone because their bytes fall outside the A–Z range. It just will not lowercase any non-ASCII letters.

More examples

Case-insensitive comparison

All three lines print bool(true). The last one shows the practical pattern: lowercase the extension before checking it against a whitelist, otherwise 'PNG' would fail a strict in_array comparison.

Example · php
<?php
$a = 'ADMIN';
$b = 'admin';

var_dump(strtolower($a) === $b);   // bool(true)
var_dump(strcasecmp($a, $b) === 0); // bool(true)

$exts = ['jpg', 'png'];
$file = 'Photo.PNG';
var_dump(in_array(strtolower(pathinfo($file, PATHINFO_EXTENSION)), $exts, true));

Normalising only the domain of an email

Prints '[email protected]'. Domains are case-insensitive by specification but local parts technically are not, so blanket-lowercasing the whole address can change its meaning.

Example · php
<?php
$email = '[email protected]';

[$local, $domain] = explode('@', $email, 2);
$normalised = $local . '@' . strtolower($domain);

echo $normalised, "\n";

Discussion

  • Be the first to comment on this lesson.