array_diff_ukey
Returns entries of the first array whose keys a user callback does not match in any other array.
array_diff_ukey(array $array, array ...$arrays, callable $key_compare_func): array- Added in PHP 5.1.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$array | array | The array to compare from. |
$arraysoptional | array | One or more arrays whose keys are compared against (variadic). |
$key_compare_func | callable | Comparison function for the keys, called as callback(mixed $a, mixed $b): int. It must return a value less than, equal to, or greater than zero. |
Return value
arrayAn array of entries from $array whose keys the callback did not report as equal to any key in the other arrays.
array_diff_ukey() is array_diff_key() with the key comparison handed to you. Values are never looked at; for each key in the first array PHP asks your callback whether it equals any key in the other arrays, and keeps the entry when the answer is always no.
When to reach for it
Reach for it when "the same key" means something looser than an identical string. Case-insensitive matching of header or environment-variable names is the common one — strcasecmp can be passed straight in. It also covers keys that carry a prefix or namespace you want to ignore, keys with stray whitespace from an imported file, and numeric-ish keys such as '007' that should match 7.
What trips people up
The callback is the last argument, after all the arrays, which is the reverse of what most people type first. Getting it wrong produces a TypeError, not a silent bug.
Your callback must be a proper three-way comparator returning a negative, zero or positive int. Returning a bool works by accident in simple cases but breaks the internal sort the function uses, so use strcmp, strcasecmp, or the spaceship operator. Floats returned by the callback are cast to int, so 0.9 becomes 0 — "equal".
Example
When to use it
- Compare environment-variable arrays where one side is upper-case and the other is not
- Find config keys missing from a provided set while ignoring a section prefix
- Match keys that arrived with padding or inconsistent zero-filling from an import
Frequently asked questions
What is the difference between array_diff_ukey and array_diff_key?
array_diff_key compares keys with a built-in string comparison, while array_diff_ukey lets you supply the comparison so keys can match case-insensitively, after trimming, or under any other rule.
Where do I put the callback?
After every array, as the final argument: array_diff_ukey($a, $b, $c, $callback). Placing it earlier raises a TypeError since that position expects an array.
Can the callback return true or false?
No — it must return a negative, zero, or positive integer like a sort comparator. The function uses the ordering internally, and booleans produce unreliable results.
More examples
Ignoring a section prefix
The callback compares only the text before the first dot, so both db.* entries match the 'db' section key and are removed. Only app.name is left, which is how you subtract a whole namespace in one call.
<?php
$config = ['db.host' => 'x', 'db.port' => 1, 'app.name' => 'shop'];
$sections = ['db' => true];
$section = fn($k) => explode('.', (string) $k)[0];
print_r(array_diff_ukey($config, $sections, fn($a, $b) => strcmp($section($a), $section($b))));Numeric-style key matching
'02' stays a string key because of the leading zero, so array_diff_key would not match it against the integer 2. Casting inside the callback makes them equal, and the output keeps only keys 1 and 3.
<?php
$a = [1 => 'one', '02' => 'two', 3 => 'three'];
$b = [2 => 'ignored'];
var_dump(array_diff_ukey($a, $b, fn($x, $y) => (int) $x <=> (int) $y));Values are never compared
Even though the values have nothing in common, 'name' is removed because its key matched 'NAME'. Use array_diff_uassoc() when the value has to match as well.
<?php
$a = ['name' => 'Ada', 'city' => 'London'];
$b = ['NAME' => 'completely different'];
print_r(array_diff_ukey($a, $b, 'strcasecmp'));
Discussion