Signature
strtoupper(string $string): stringPurpose
strtoupper() returns a copy of a string in which every ASCII lowercase letter has been replaced by its uppercase form. It is a small, fast tool for normalizing identifiers, coupon codes, header names, and other machine-oriented text where you want a single canonical spelling.
The function works on bytes. Each byte from a (0x61) to z (0x7a) is converted by subtracting 32. Every other byte is copied unchanged, including digits, punctuation, whitespace and any byte that belongs to a multibyte character. The original string is never modified; you must use the returned value.
Signature
Parameters and defaults
$string: the input string. It is required and has no default value.
There are no optional parameters. In particular, you cannot pass a locale or an encoding. The documented changelog states that since PHP 8.2.0 the conversion no longer depends on the locale set with setlocale(), and only ASCII characters are converted. So the result for a given input is the same on every machine running PHP 8.4.
Return value and failure cases
The function always returns a string, and the result has the same length in bytes as the input. It does not return false and does not signal failure through a return value.
Because the parameter is typed string, wrong argument types are handled by PHP's normal type rules:
- Passing an array (or an object without
__toString()) throws aTypeError. - In the default coercive typing mode, a scalar such as an integer is converted to its string form first, so
strtoupper(123)gives"123". - With
declare(strict_types=1);in the calling file, passing an integer throws aTypeErrorinstead of being coerced.
The manual also notes that the function is binary-safe, meaning strings containing NUL bytes are processed in full rather than being cut off.
Example 1: normalizing a code
User input often arrives with stray spaces and mixed case. Combining trim() and strtoupper() gives a stable form for lookups.
$input = " save10 ";
$code = strtoupper(trim($input));
echo $code, "\n";SAVE10
The output is SAVE10 followed by a newline. Note that trim() removes the surrounding whitespace first; strtoupper() does not touch whitespace.
Example 2: UTF-8 text is only partly converted
Because only ASCII letters are changed, accented letters and other non-ASCII characters keep their original case. The multibyte bytes are simply ignored, so the UTF-8 text stays valid, but it may look half-converted.
$text = "café ñandú straße";
echo json_encode(['upper' => strtoupper($text)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"upper":"CAFé ñANDú STRAßE"}The result is {"upper":"CAFé ñANDú STRAßE"}. The letters c, a, f, a, n, d and so on are uppercased, but é, ñ, ú and ß are left as they were. If you need full Unicode case conversion, the manual points to mb_strtoupper(), which belongs to the mbstring extension.
Example 3: canonical array keys
HTTP-style header names are case-insensitive, so a common pattern is to rebuild an array with uppercased keys.
$headers = ["content-type" => "text/plain", "X-Request-Id" => "abc"];
$normalized = [];
foreach ($headers as $name => $value) {
$normalized[strtoupper($name)] = $value;
}
echo json_encode($normalized, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"CONTENT-TYPE":"text/plain","X-REQUEST-ID":"abc"}The output is {"CONTENT-TYPE":"text/plain","X-REQUEST-ID":"abc"}. Only the keys change; the values keep their original case, which matters because text/plain is data, not a name.
Edge cases
- Empty string: returns an empty string.
- No letters: a string such as
"123-456"is returned unchanged. - Already uppercase: the result equals the input.
- Collisions: two different keys such as
"id"and"ID"become identical after conversion. When you rebuild an array, the later one overwrites the earlier one. - Non-UTF-8 bytes: bytes outside the ASCII lowercase range are never altered, so legacy single-byte encodings are not converted either.
- Length: the result has the same byte length as the input, unlike full Unicode uppercasing, where one character can expand into several (for example
ßtoSS).
Common mistakes
- Ignoring the return value. Writing
strtoupper($name);on its own statement has no effect. Assign the result:$name = strtoupper($name);. - Expecting Unicode support. Names like
"Zoë"will become"ZOë". Usemb_strtoupper()for human-language text in non-ASCII scripts, provided the mbstring extension is available. - Relying on locale. Older advice suggested calling
setlocale()to change how accented letters convert. As the changelog says, since PHP 8.2.0 the locale no longer affects this function. - Using it for display capitalization. Uppercasing every character is not the same as title case. Look at
ucfirst()orucwords()when you want to capitalize only initial letters. - Passing arrays. Passing an array throws a
TypeError; apply the function to each element, for example witharray_map(). - Comparing before normalizing both sides. When doing a case-insensitive comparison, convert both strings the same way, or use a dedicated function like
strcasecmp().
Related functions
strtolower(): makes a string lowercase, using the same ASCII-only rule.ucfirst(): uppercases only the first character.ucwords(): uppercases the first character of each word.mb_strtoupper(): converts multibyte characters, not just ASCII.
Recap
strtoupper() takes one string and returns a new string where ASCII a to z are turned into A to Z. Everything else, including UTF-8 multibyte characters, passes through unchanged. Since PHP 8.2.0 it ignores the current locale. Use it for normalizing ASCII identifiers and keys, always use the returned value, and switch to mb_strtoupper() when real Unicode case mapping is needed.
Tested examples
$input = " save10 ";
$code = strtoupper(trim($input));
echo $code, "\n";SAVE10
$text = "café ñandú straße";
echo json_encode(['upper' => strtoupper($text)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"upper":"CAFé ñANDú STRAßE"}
$headers = ["content-type" => "text/plain", "X-Request-Id" => "abc"];
$normalized = [];
foreach ($headers as $name => $value) {
$normalized[strtoupper($name)] = $value;
}
echo json_encode($normalized, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"CONTENT-TYPE":"text/plain","X-REQUEST-ID":"abc"}