Signature
array_intersect_ukey(array $array, array ...$arrays, callable $key_compare_func): arrayPurpose
array_intersect_ukey() filters one array by comparing its keys with the keys of one or more other arrays. You supply the comparison callback, so you decide when two keys count as the same. It returns the entries of the first array whose keys match a key in every other array. Values are never compared.
Use it when plain array_intersect_key() is too strict, for example when keys differ only in case, or carry a prefix or other formatting noise.
Signature
Parameters
$array: the array to filter. Its keys, values and order form the result....$arrays: the arrays whose keys are checked against. A key must be found in all of them to survive.$key_compare_func: the last argument. It receives two keys and must return an integer below zero, zero, or above zero, like the callbacks used by sorting functions. There is no default; the callback is required.
The callback is declared as function callback(mixed $a, mixed $b): int. Returning a float is risky because it is cast to an integer: 0.5 becomes 0 and is treated as a match.
Return value and failures
The function returns an array containing the entries of $array whose keys match in every other array. Original keys are preserved and the order of $array is kept. If nothing matches, the result is an empty array.
Passing something that is not an array where an array is expected, or a value that is not callable as the final argument, raises a TypeError.
Example 1: case-insensitive keys
Passing strcasecmp as the callback makes Red and red count as the same key. The surviving entries keep the spelling and values from the first array.
$a = ['Red' => 1, 'GREEN' => 2, 'blue' => 3];
$b = ['red' => 10, 'Green' => 20, 'yellow' => 30];
$result = array_intersect_ukey($a, $b, 'strcasecmp');
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"Red":1,"GREEN":2}
Example 2: several arrays and integer keys
With more than two arrays, a key must appear in all of them. Here only keys 3 and 4 exist in every array. The spaceship operator is a compact way to write an integer comparison.
$base = [1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd'];
$second = [2 => 'x', 3 => 'y', 4 => 'z'];
$third = [3 => 'p', 4 => 'q', 5 => 'r'];
$result = array_intersect_ukey($base, $second, $third, fn(int $a, int $b): int => $a <=> $b);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"3":"c","4":"d"}
Example 3: ignoring a key prefix
A custom callback can normalise keys before comparing them. This one strips leading underscores, so _host matches host and port matches _port.
$config = ['_host' => 'localhost', 'port' => 80, '_debug' => true];
$allowed = ['host' => 1, '_port' => 1];
$result = array_intersect_ukey(
$config,
$allowed,
fn($a, $b) => strcmp(ltrim((string) $a, '_'), ltrim((string) $b, '_'))
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"_host":"localhost","port":80}
Edge cases
- Values are ignored. Two entries with the same matching key are kept even if their values differ. The values returned always come from the first array.
- Only the first array contributes entries. Values from the other arrays never appear in the result.
- Key order is not rearranged. The result follows the order of the first array, not the order of the callback comparisons.
- Numeric string keys become integers. PHP converts a key like
"3"to the integer3when the array is created, so your callback may receive integers even if you wrote strings. Cast inside the callback if you need string operations. - Several keys may match. If a callback treats different keys as equal, such as
aandA, each entry in the first array is checked on its own, so both can be kept when a match exists.
Common mistakes
- Putting the callback first. The callback must be the last argument, after every array.
- Expecting values to be compared. To compare values too, look at the associative or value-based intersect functions listed below.
- Writing an inconsistent callback. A callback that returns only
0or1, or sometimes disagrees when the arguments are swapped, produces unreliable matches. Return negative, zero and positive consistently. - Returning a boolean or a float. A callback such as
fn($a, $b) => $a == $breturnstruefor equal keys, the opposite of the convention, because zero means equal. Return an integer, ideally from<=>orstrcmp(). - Using it when exact matching is enough. If the standard key equality works,
array_intersect_key()is simpler and does not need a callback.
Related functions
array_intersect_key(): the same key intersection with built-in key comparison.array_intersect_uassoc(): compares keys with a callback and values with the standard comparison.array_intersect_assoc(): requires both key and value to match.array_intersect(): compares values only.array_diff_ukey(): the opposite operation, keeping entries whose keys do not match under a callback.
Recap
array_intersect_ukey() returns the entries of the first array whose keys match, under your callback, in all the other arrays. The callback comes last and must return an integer: zero for equal keys. Values are not compared, original keys and order are preserved, and the result is an empty array when no keys match.
Tested examples
$a = ['Red' => 1, 'GREEN' => 2, 'blue' => 3];
$b = ['red' => 10, 'Green' => 20, 'yellow' => 30];
$result = array_intersect_ukey($a, $b, 'strcasecmp');
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
{"Red":1,"GREEN":2}
$base = [1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd'];
$second = [2 => 'x', 3 => 'y', 4 => 'z'];
$third = [3 => 'p', 4 => 'q', 5 => 'r'];
$result = array_intersect_ukey($base, $second, $third, fn(int $a, int $b): int => $a <=> $b);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
{"3":"c","4":"d"}
$config = ['_host' => 'localhost', 'port' => 80, '_debug' => true];
$allowed = ['host' => 1, '_port' => 1];
$result = array_intersect_ukey(
$config,
$allowed,
fn($a, $b) => strcmp(ltrim((string) $a, '_'), ltrim((string) $b, '_'))
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
{"_host":"localhost","port":80}