Strings7 min readExamples run on PHP 8.5.10

strtolower()

Learn how PHP 8.4 strtolower() lowercases ASCII letters in a string, what it leaves alone, and which mistakes to avoid with non-ASCII text.

Signature

strtolower(string $string): string

Purpose

strtolower() returns a copy of a string in which every ASCII uppercase letter has been replaced by its lowercase counterpart. It is the standard tool for making simple, predictable text comparisons, building normalized array keys, and tidying identifiers such as email addresses, slugs or option names that you know are plain ASCII.

The function works on bytes. A byte from A (0x41) to Z (0x5a) gets 32 added to it, and every other byte is passed through untouched. That simple rule explains almost all of its behavior.

Signature

Parameters and defaults

  • $string is the input text. It is required and has no default value.

There are no flags, no locale argument and no optional parameters. Since PHP 8.2 the result no longer depends on the locale set with setlocale(), so the same input gives the same output on every server.

Return value and failure cases

The function always returns a new string; the original variable is not modified. An empty string gives back an empty string. The function does not return false and does not emit warnings for ordinary text.

The only failures come from the type of the argument. Passing an array, or an object that cannot be converted to a string, throws a TypeError. Under declare(strict_types=1) even an integer is rejected, while in the default coercive mode an integer or float is converted to a string first. Avoid passing null; check for it and decide what an absent value should mean in your program.

Example 1: Basic lowercasing

The simplest use is converting a mixed-case sentence.

Example
<?php
$title = "Mary Had A Little Lamb";
echo strtolower($title), "\n";
Output
mary had a little lamb

Every capital letter becomes lowercase, and spaces are unchanged.

Example 2: Normalizing keys

Lowercasing before storing a value is a common way to treat differently capitalized spellings as the same item. Here the array keys collapse duplicates.

Example
<?php
$emails = ["Ann@Example.COM", "ann@example.com", "BOB@example.com"];
$unique = [];
foreach ($emails as $email) {
    $unique[strtolower($email)] = true;
}
echo json_encode(array_keys($unique), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["ann@example.com","bob@example.com"]

The first two addresses differ only in case, so they map to one key. Whether email addresses should really be treated case-insensitively is a policy decision for your application; the function simply performs the conversion you ask for.

Example 3: Non-ASCII characters are ignored

The documentation notes that multibyte UTF-8 characters are ignored. Only the ASCII letters in the string change.

Example
<?php
$text = "ÄPFEL ABC";
echo json_encode(strtolower($text), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
"Äpfel abc"

The capital Ä survives because it is not in the ASCII range, while PFEL ABC is lowercased. This is safe for UTF-8 strings, since the bytes of multibyte characters never fall in the range that gets modified, but it is not real Unicode case conversion.

Edge cases

  • Digits, punctuation, whitespace and control characters are returned unchanged.
  • The function is binary-safe, so strings containing null bytes are processed completely rather than being cut short.
  • Strings that are already lowercase come back with identical contents.
  • Because accented letters and letters from other alphabets are not touched, strtolower() cannot be used to compare text such as German, Greek or Turkish words case-insensitively.

Common mistakes

  1. Expecting Unicode support. For text that may contain non-ASCII letters, use mb_strtolower() from the mbstring extension, which understands multibyte encodings.
  2. Relying on the locale. Older code sometimes called setlocale() to make this function handle accented letters. Since PHP 8.2 the locale has no effect, and only ASCII characters are converted.
  3. Ignoring the return value. Writing strtolower($name); on its own line does nothing useful. Assign the result, for example $name = strtolower($name);.
  4. Lowercasing only one side of a comparison. If you compare strtolower($a) with $b and $b still has capitals, the test fails. Normalize both sides, or use a dedicated case-insensitive function such as strcasecmp().
  5. Using it for security-sensitive normalization without thought. Lowercasing ASCII does not unify visually similar Unicode characters, so do not assume it fully canonicalizes user input.
  • strtoupper() converts ASCII letters to uppercase.
  • ucfirst() uppercases only the first character.
  • ucwords() uppercases the first character of each word.
  • mb_strtolower() lowercases multibyte text according to Unicode rules.

Recap

strtolower() takes one string and returns a new string with ASCII A to Z changed to a to z. Everything else, including UTF-8 multibyte characters, stays as it was. Use it for simple ASCII normalization, assign its result, and reach for mb_strtolower() when the text is genuinely international.

Tested examples

Basic lowercasing of a sentence
<?php
$title = "Mary Had A Little Lamb";
echo strtolower($title), "\n";
Output
mary had a little lamb
Normalizing array keys to remove case duplicates
<?php
$emails = ["Ann@Example.COM", "ann@example.com", "BOB@example.com"];
$unique = [];
foreach ($emails as $email) {
    $unique[strtolower($email)] = true;
}
echo json_encode(array_keys($unique), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["ann@example.com","bob@example.com"]
Non-ASCII characters are left unchanged
<?php
$text = "ÄPFEL ABC";
echo json_encode(strtolower($text), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
"Äpfel abc"