Arrays7 min readExamples run on PHP 8.5.10

array_change_key_case()

Learn how array_change_key_case() lowercases or uppercases string keys in PHP 8.4, what it returns, how key collisions behave, and which mistakes to avoid.

Signature

array_change_key_case(array $array, int $case = CASE_LOWER): array
Available since PHP 4.2.07.48.08.18.28.38.48.5All versions →

Purpose

array_change_key_case() returns a copy of an array in which every string key has been converted to lowercase or uppercase. It is useful when the keys come from a source that does not agree on capitalization, such as HTTP header names, CSV column titles or configuration entries, and you want to look them up in one predictable form.

The function only touches keys. Values are copied unchanged, and integer keys are left as they are.

Signature

Parameters and defaults

  • $array: the input array. It is not modified, because PHP passes it by value and the function builds a new array.
  • $case: either CASE_LOWER or CASE_UPPER. The default is CASE_LOWER, so calling the function with one argument lowercases the keys. Pass one of the two named constants rather than a raw number, so the intent is clear.

Return value and failure cases

The function returns a new array with the converted keys. There is no false return and no warning for a normal array, including an empty one, which simply gives back an empty array. Passing something that is not an array, such as a string or null, throws a TypeError, because the parameter is typed as array.

Example 1: normalizing header names

The default mode lowercases keys, which makes later lookups simple.

Example
<?php
$headers = ['Content-Type' => 'text/html', 'X-Request-ID' => 'abc123'];
echo json_encode(array_change_key_case($headers), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"content-type":"text/html","x-request-id":"abc123"}

The keys become content-type and x-request-id, and the values keep their original case.

Example 2: uppercase mode and numeric keys

Integer keys have no case, so they pass through untouched, in their original position.

Example
<?php
$data = ['a' => 1, 5 => 'five', 'b' => 2];
echo json_encode(array_change_key_case($data, CASE_UPPER), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"A":1,"5":"five","B":2}

Only a and b change. The key 5 stays an integer, and the order of the entries is preserved.

Example 3: keys that collide

Two keys that differ only by case become the same key after conversion. The manual notes that the value that appears later in the array wins.

Example
<?php
$data = ['Name' => 'first', 'Age' => 30, 'NAME' => 'second'];
echo json_encode(array_change_key_case($data, CASE_LOWER), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"name":"second","age":30}

The later value second replaces first. The surviving name entry stays at the position where that key first appeared, which is ordinary PHP array assignment behavior. One entry is lost silently, and no warning is raised.

Edge cases

  • Collisions lose data. If you cannot rule out keys such as Name and NAME in the same array, check for duplicates first. One way is to compare count() before and after the call.
  • Not recursive. Only the top-level keys are converted. Keys inside nested arrays keep their original case. If you need deeper conversion, write a small recursive function around array_change_key_case().
  • Numeric strings. A key such as "10" is already stored as the integer 10 by PHP, so it is treated like any integer key.
  • Letters outside plain ASCII. This page does not document any multibyte handling. If your keys contain accented or non-Latin letters and you need Unicode-aware conversion, build the new array yourself and convert keys with mb_strtolower() or mb_strtoupper().
  • Empty arrays. An empty array returns an empty array.

Common mistakes

  1. Expecting in-place modification. The function does not change the variable you pass in. Assign the result, for example $headers = array_change_key_case($headers);.
  2. Forgetting the default is lowercase. If you want uppercase keys, you must pass CASE_UPPER explicitly.
  3. Ignoring collisions. Normalizing user-supplied keys can overwrite values without any notice.
  4. Assuming values are converted. Only keys change. To change values as well, combine this function with array_map().
  5. Expecting nested conversion. Sub-arrays are copied as they are.
  6. Passing a non-array. Values such as null from a missing configuration section cause a TypeError, so validate or default to [] first.
  • array_keys() returns the keys of an array, which helps when you need to inspect them.
  • array_combine() builds an array from a list of keys and a list of values. Combined with array_map(), it allows custom key transformations.
  • array_map() transforms values, which array_change_key_case() does not do.
  • strtolower() and strtoupper() perform the same ASCII conversions on single strings.
  • mb_strtolower() and mb_strtoupper() are the multibyte-aware counterparts for single strings.

Recap

array_change_key_case($array, $case) returns a new array whose string keys are lowercased (the default, CASE_LOWER) or uppercased (CASE_UPPER). Integer keys and all values stay unchanged, nested arrays are not processed, and colliding keys overwrite earlier ones with the later value. Assign the returned array, and guard against collisions when the key source is untrusted.

Tested examples

Lowercase header names with the default mode
<?php
$headers = ['Content-Type' => 'text/html', 'X-Request-ID' => 'abc123'];
echo json_encode(array_change_key_case($headers), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"content-type":"text/html","x-request-id":"abc123"}
Uppercase keys while integer keys stay unchanged
<?php
$data = ['a' => 1, 5 => 'five', 'b' => 2];
echo json_encode(array_change_key_case($data, CASE_UPPER), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"A":1,"5":"five","B":2}
Colliding keys: the later value wins
<?php
$data = ['Name' => 'first', 'Age' => 30, 'NAME' => 'second'];
echo json_encode(array_change_key_case($data, CASE_LOWER), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"name":"second","age":30}