array_udiff_assoc
Returns entries of the first array whose key/value pair is absent from the others, comparing values with a callback.
array_udiff_assoc(array $array, array ...$arrays, callable $value_compare_func): array- Added in PHP 5.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$array | array | The first array, whose entries are the candidates for the result. |
$arrays | array | One or more arrays to compare against. Variadic. |
$value_compare_func | callable | Comparison function with the signature callback(mixed $a, mixed $b): int, used for the values only. Keys are compared internally with the standard comparison. Always the last argument. |
Return value
arrayAn array of entries from $array whose key/value combination is not present in any of the other arrays.
Errors
Throws a TypeError if fewer than three arguments are supplied, if any array argument is not an array, or if the last argument is not callable.
array_udiff_assoc() keeps an entry from the first array when no other array has the same key holding an equal value. Keys are matched with PHP's built-in comparison; only the values go through your callback.
When to reach for it
This is the "what changed" function for two associative records. Compare a saved row against a submitted form and you get exactly the fields whose values differ, keyed by field name — ideal for building an audit log or a partial UPDATE. Use it instead of array_diff_assoc() when the values are objects, floats needing a tolerance, or strings needing a case-insensitive or normalised match.
What trips people up
It only reports fields the first array has. A key present in the second array but missing from the first never appears in the result. To detect additions as well as changes, run the diff both ways and merge, or compare against the union of keys.
As with all the u* functions, the callback is the last argument and must return an integer ordering, not a boolean. And note the asymmetry with its siblings: here the value comparison is yours and the key comparison is built in. If you need the reverse — a custom key comparison with standard value comparison — that is array_diff_uassoc().
Example
When to use it
- Build an audit trail of exactly which fields a user changed on a form submission.
- Produce a partial UPDATE payload containing only the columns whose values actually differ.
- Compare two configuration maps where values are objects or need normalised comparison.
Frequently asked questions
What is the difference between array_udiff and array_udiff_assoc?
array_udiff compares values anywhere in the other arrays, ignoring keys; array_udiff_assoc requires the key to match as well, so it reports entries whose value changed under the same key.
Does array_udiff_assoc use my callback for the keys?
No, only for the values. Keys are compared with PHP's standard comparison. If you need a custom key comparison instead, use array_diff_uassoc.
Why are keys that exist only in the second array missing from the result?
The result is always a subset of the first array, so additions are invisible. Run the diff a second time with the arguments swapped to find them.
More examples
Key must match too
array_udiff finds nothing to report because both values exist somewhere in $b. array_udiff_assoc returns both entries, because under key 'x' the values differ and under key 'y' they differ too.
<?php
$a = ['x' => 'one', 'y' => 'two'];
$b = ['y' => 'one', 'x' => 'two'];
print_r(array_udiff($a, $b, 'strcmp'));
print_r(array_udiff_assoc($a, $b, 'strcmp'));Diffing in both directions
The first call reports only b, because c does not exist in $old. The second call reports b and c, revealing the added key. Running both directions is how you get a complete change set.
<?php
$old = ['a' => 1, 'b' => 2];
$new = ['a' => 1, 'b' => 9, 'c' => 3];
$cmp = fn($p, $q) => $p <=> $q;
print_r(array_udiff_assoc($old, $new, $cmp)); // changed or removed
print_r(array_udiff_assoc($new, $old, $cmp)); // changed or addedNumeric tolerance on values
temp is treated as unchanged because it is within tolerance, so only humidity => 55 is reported. A plain array_diff_assoc would have flagged temp as different.
<?php
$reading = ['temp' => 20.001, 'humidity' => 55.0];
$baseline = ['temp' => 20.0, 'humidity' => 61.0];
$near = fn($a, $b) => abs($a - $b) < 0.01 ? 0 : ($a <=> $b);
print_r(array_udiff_assoc($reading, $baseline, $near));
Discussion