array_change_key_case

Returns a copy of an array with all string keys converted to lower or upper case.

Signature
array_change_key_case(array $array, int $case = CASE_LOWER): array
  • Added in PHP 4.2.0

Parameters

ParameterTypeDescription
$arrayarrayThe array whose keys should be converted.
$caseoptionalint= CASE_LOWEREither CASE_LOWER (the default) or CASE_UPPER.

Return value

arrayA copy of the array with every string key converted to the requested case. Integer keys are returned unchanged.

Conversion is plain byte-wise ASCII casing, independent of locale. Only the ASCII letters of a key are converted; bytes outside A–Z/a–z are left untouched, so the accented characters — not the whole key — survive: ÉTAT comes back as État and Straße as straße under CASE_LOWER. Convert those yourself with mb_convert_case() over array_keys() and rebuild with array_combine().

Example

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

When to use it

  • Normalise HTTP header names before looking up 'content-type'
  • Lower-case CSV header columns so row lookups do not depend on the exporter's capitalisation
  • Make config arrays merged from .env, .ini and defaults use one consistent key case

Frequently asked questions

Does array_change_key_case work on nested arrays?

No, it only converts keys at the top level of the array. Values that are themselves arrays are copied as-is with their original keys, so you need a small recursive function if you want the whole structure normalised.

Why are my numeric keys not changing?

Numeric keys are integers, and integers have no case. The function deliberately leaves them exactly as they are, including string keys such as '20' that PHP has already converted to the integer 20.

Does array_change_key_case handle accented or UTF-8 keys?

Not reliably — it applies plain ASCII case conversion, so only the ASCII letters of a key are changed and non-ASCII bytes are left as they are: 'ÉTAT' comes back as 'État', not unchanged and not fully lower-cased. For multibyte keys, map mb_convert_case() over array_keys() and rebuild the array with array_combine().

More examples

Numeric keys are left alone

The output shows only 'Name' and 'ID' were rewritten to 'name' and 'id'. The key 10 and the string '20' are both stored as integers, so the function skips them entirely — casing only applies to string keys.

Example · php
<?php
$mixed = ['Name' => 'Ada', 10 => 'ten', 'ID' => 42, '20' => 'twenty'];

var_dump(array_change_key_case($mixed, CASE_LOWER));

Colliding keys silently overwrite

All three keys become 'key', so only the last value survives: the result is one entry with 'third'. Count the array before and after when the source may contain near-duplicate keys.

Example · php
<?php
$input = ['keY' => 'first', 'Key' => 'second', 'KEY' => 'third'];

$out = array_change_key_case($input, CASE_LOWER);
print_r($out);
echo "kept ", count($out), " of ", count($input), " entries\n";

Making it recursive

The built-in only touches the outer level, so the nested HOST/PORT keys would normally survive as-is. This four-line wrapper walks into every sub-array, and the output shows db.host and db.port fully lower-cased.

Example · php
<?php
function keysToLower(array $a): array {
    $a = array_change_key_case($a, CASE_LOWER);
    foreach ($a as $k => $v) {
        if (is_array($v)) { $a[$k] = keysToLower($v); }
    }
    return $a;
}

print_r(keysToLower(['DB' => ['HOST' => 'localhost', 'PORT' => 5432], 'Debug' => true]));

Discussion

  • Be the first to comment on this lesson.