Arrays7 min readExamples run on PHP 8.5.10

array_diff_key()

Learn how array_diff_key() removes entries by key, how it handles several arrays, and which mistakes to avoid when filtering PHP arrays.

Signature

array_diff_key(array $array, array ...$arrays): array
Available since PHP 5.1.07.48.08.18.28.38.48.5All versions →

Purpose

array_diff_key() keeps the entries of one array whose keys do not appear in any of the other arrays you pass. It is the key-based sibling of array_diff(), which compares values. Use it when the question is "which named fields are missing from this other set?" rather than "which values differ?"

Typical uses include dropping fields that were already handled, removing a set of blocked keys from a configuration array, and finding which keys of an input array are not on an allowed list.

Signature

Parameters and defaults

  • $array: the array to compare from. Its entries are the only ones that can appear in the result.
  • ...$arrays: zero or more arrays to compare against. An entry from $array is removed if its key exists in any of them.

There are no other defaults. Since PHP 8.0 the function may be called with just one argument; in that case nothing is compared against, so you simply get the entries of $array back.

Return value and failures

The function returns a new array containing the entries of $array whose keys are absent from all the other arrays. Keys and values of the surviving entries are preserved exactly, and the original order is kept. The input arrays are not modified.

If an argument is not an array, PHP throws a TypeError. An empty result is just an empty array, not an error.

Example 1: removing overridden settings

Here the keys present in $overrides are dropped from $defaults. Only the keys matter; the values of $overrides are never looked at.

Example
<?php
$defaults = ['host' => 'localhost', 'port' => 3306, 'debug' => false];
$overrides = ['port' => 3307, 'user' => 'app'];
echo json_encode(array_diff_key($defaults, $overrides), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"host":"localhost","debug":false}

The key user exists only in $overrides, so it has no effect on the result.

Example 2: comparing against several arrays

With more than one comparison array, a key is removed if it appears in at least one of them. Differing values do not save an entry: green is removed even though its values differ between the arrays.

Example
<?php
$all = ['blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4];
$first = ['green' => 5, 'yellow' => 7];
$second = ['blue' => 6, 'mauve' => 8];
$result = array_diff_key($all, $first, $second);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"red":2,"purple":4}

Example 3: numeric keys are preserved

Numeric keys are compared like any other key and are not renumbered. Removing positions from a list therefore leaves gaps, which changes how the array is encoded as JSON. Use array_values() when you need a fresh list.

Example
<?php
$list = ['a', 'b', 'c', 'd'];
$remove = [1 => true, 3 => true];
$rest = array_diff_key($list, $remove);
echo json_encode($rest, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_values($rest), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"0":"a","2":"c"}
["a","c"]

The first line is an object because the keys are 0 and 2, not a gap-free sequence starting at zero.

Edge cases

  • Values are ignored. A key counts as present even if its value is null, false or an empty string.
  • Key equality is string-based. Two keys match only when their string forms are identical. PHP also normalizes array keys, so the string key "1" and the integer key 1 are the same key in an array.
  • Only the top level is compared. Nested arrays are not walked. To compare a deeper level, call the function on the nested arrays directly, for example on $a['options'] and $b['options'].
  • Order comes from the first array. Arguments after the first never change the order of the result.
  • One argument is allowed. The result is simply the same entries as the input.

Common mistakes

  1. Expecting value comparison. If you want to remove entries by value, use array_diff(). If both key and value must match, use array_diff_assoc().
  2. Passing a list of key names. array_diff_key($data, ['id', 'name']) compares against keys 0 and 1, not against id and name. Flip the list first with array_flip() so the names become keys.
  3. Forgetting that keys are preserved. After filtering a list, the result may no longer be a list. Re-index with array_values() if later code assumes sequential keys.
  4. Assuming the original array changes. The function returns a new array; assign it or use it directly.
  5. Expecting recursive behavior. Nested differences are not detected, because only top-level keys are compared.
  • array_diff() compares values instead of keys.
  • array_diff_assoc() requires both key and value to match before removing an entry.
  • array_diff_ukey() lets a callback decide whether keys are equal.
  • array_intersect_key() keeps entries whose keys appear in the other arrays, the opposite filter.
  • array_flip() and array_values() help prepare key lists and re-index results.

Recap

array_diff_key() returns the entries of the first array whose keys do not occur in any later array. Values in the later arrays are irrelevant, keys and order of the survivors are preserved, and only the top dimension is checked. Remember to re-index when you need a list, and to flip key-name lists before using them as the comparison set.

Tested examples

Removing overridden settings
<?php
$defaults = ['host' => 'localhost', 'port' => 3306, 'debug' => false];
$overrides = ['port' => 3307, 'user' => 'app'];
echo json_encode(array_diff_key($defaults, $overrides), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"host":"localhost","debug":false}
Comparing against several arrays
<?php
$all = ['blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4];
$first = ['green' => 5, 'yellow' => 7];
$second = ['blue' => 6, 'mauve' => 8];
$result = array_diff_key($all, $first, $second);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"red":2,"purple":4}
Numeric keys are preserved
<?php
$list = ['a', 'b', 'c', 'd'];
$remove = [1 => true, 3 => true];
$rest = array_diff_key($list, $remove);
echo json_encode($rest, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_values($rest), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"0":"a","2":"c"}
["a","c"]