W3docs

Using array_udiff_uassoc in PHP

Learn how to use the PHP function array_udiff_uassoc to calculate the difference between two or more arrays using a user-defined comparison function.

array_udiff_uassoc() computes the difference of two or more arrays while checking both keys and values — and it lets you decide how both are compared by supplying two of your own callbacks. An element from the first array is kept in the result only if no other array contains an element that matches it on both the key and the value, according to your callbacks.

This page explains exactly how the two callbacks interact (the part most reference docs gloss over), walks through a runnable example, and shows when this function is the right tool versus its simpler siblings.

What is array_udiff_uassoc?

array_udiff_uassoc() returns the entries of $array1 that are not present in any of the other arrays. Unlike array_diff(), which compares values only with string casting, this variant checks keys and values together and delegates both comparisons to user-supplied functions — that is what the two us in the name mean (udiff = user value compare, uassoc = user key compare).

The signature is:

PHP array_udiff_uassoc function syntax

array_udiff_uassoc(
    array $array1,
    array $array2,
    array ...$arrays,        // one or more additional arrays
    callable $value_compare_func,
    callable $key_compare_func
): array

The two callbacks are always the last two arguments, in this order: value comparison first, key comparison second. Everything before them is an array. The result is a new array of the entries from $array1 that survive the comparison, with their original keys preserved.

How the matching actually works. For each entry in $array1, PHP looks through the other arrays for an entry whose key is "equal" per $key_compare_func and whose value is "equal" per $value_compare_func. If such a match exists in any other array, the entry is dropped; otherwise it is kept. An entry is removed only when both comparisons report equality.

Understanding the comparison functions

Each callback receives two arguments and must return an integer, exactly like a sort comparator:

  • Return 0 when the two items are considered equal.
  • Return a positive integer when the first is "greater".
  • Return a negative integer when the first is "less".

PHP only cares whether the return value is 0 (equal) or not, but a consistent three-way result is required because the function sorts internally. The spaceship operator <=> is the easiest way to write one:

$value_compare_func = fn($a, $b) => $a <=> $b;   // strict ordering
$key_compare_func   = fn($a, $b) => strcasecmp((string) $a, (string) $b); // case-insensitive keys

Because you define both comparisons, you can do things the built-in diff functions can't — for example, treat keys case-insensitively, or compare objects by a single property.

Example: basic usage

<?php

function compare_values($a, $b) {
    if ($a === $b) {
        return 0;
    }
    return ($a > $b) ? 1 : -1;
}

function compare_keys($a, $b) {
    if ($a === $b) {
        return 0;
    }
    return ($a > $b) ? 1 : -1;
}

$array1 = array('a' => 'apple', 'b' => 'banana', 'c' => 'cherry', 'd' => 'durian');
$array2 = array('a' => 'apple', 'b' => 'game', 'c' => 'cherry');
$array3 = array('a' => 'apple', 'b' => 'door', 'c' => 'cherry', 'g' => 'durian');

$result = array_udiff_uassoc($array1, $array2, $array3,  'compare_values', 'compare_keys');

print_r($result);

?>

Here compare_values and compare_keys are plain three-way comparators. The call diffs $array1 against $array2 and $array3, keeping only entries whose key and value are not matched anywhere else. The output is:

Array
(
    [b] => banana
    [d] => durian
)

Walk through why each entry survives or is dropped:

  • a => apple — dropped: $array2 (and $array3) has the same key a and same value apple.
  • b => bananakept: the other arrays use key b, but their values are game / door, not banana. The values differ, so it is not matched.
  • c => cherry — dropped: matched by both other arrays.
  • d => duriankept: $array3 contains the value durian, but under key g, not d. The keys differ, so it is not matched.

That last case is the whole point of the function: even though the value durian exists elsewhere, the key doesn't match, so the entry stays. A value-only diff like array_udiff() would have removed it.

Example: case-insensitive keys

Because the key comparison is yours to define, you can ignore key casing while still matching values strictly:

<?php

$wanted  = ['x' => 10, 'y' => 20, 'z' => 30];
$current = ['x' => 10, 'Y' => 20, 'z' => 99];

$result = array_udiff_uassoc(
    $wanted,
    $current,
    fn($v1, $v2) => $v1 <=> $v2,                       // values: strict ordering
    fn($k1, $k2) => strcasecmp((string) $k1, (string) $k2) // keys: case-insensitive
);

print_r($result);

Output:

Array
(
    [z] => 30
)

x => 10 and y => 20 are removed (current has the same value under a key that matches case-insensitively), while z => 30 survives because current has z => 99 — the key matches but the value 99 !== 30.

When to use it (and what to use instead)

Reach for array_udiff_uassoc() only when you need custom logic for both the keys and the values. If you need less, a simpler relative is faster to read and write:

You need to control…Use
Values only (callback), keys ignoredarray_udiff()
Values (callback) + keys with ===array_udiff_assoc()
Keys (callback) + values with ===array_diff_uassoc()
Neither — plain value diffarray_diff()

Common gotchas

  • Argument order. The callbacks are the last two arguments, value-compare first. Passing them in the wrong order silently produces wrong results rather than an error.
  • At least two arrays. You must pass $array1, at least one other array, and then both callbacks — five arguments minimum.
  • Return an int, not a bool. Returning true/false from a comparator works by accident (they cast to 1/0) but breaks ordering. Use <=> or an explicit -1/0/1.
  • Keys are preserved. The result keeps the original keys of $array1; it is not re-indexed.

If callbacks are new to you, see PHP Callback Functions, and for a refresher on arrays in general, PHP Arrays.

Conclusion

array_udiff_uassoc() is the most flexible of PHP's array-difference functions: it compares entries on both key and value, and hands both comparisons to your own callbacks. An entry from the first array survives only when no other array matches it on both dimensions. Use it when the built-in comparison rules (===, string casting) aren't enough — for example case-insensitive keys, locale-aware values, or comparing objects by a field — and fall back to a simpler array_diff* variant when you don't need that much control.

Practice

Practice
What is the functionality of the array_udiff_uassoc function in PHP?
What is the functionality of the array_udiff_uassoc function in PHP?
Was this page helpful?