W3docs

PHP's array_udiff_assoc() Function Explained

Learn how PHP's array_udiff_assoc() works: it diffs arrays by key and a custom value callback. Covers syntax, examples, objects, and gotchas.

array_udiff_assoc() compares two or more arrays and returns the entries from the first array that don't appear in any of the others. What makes it special is how it compares: keys are compared with built-in strict checking, while values are compared by a callback function you supply. This page explains the signature, walks through working examples (strings, multiple arrays, and objects), and covers the gotchas that trip people up.

Syntax

array_udiff_assoc(
    array $array,
    array ...$arrays,
    callable $value_compare_func
): array
  • $array — the array to compare from. Only its entries can appear in the result.
  • ...$arrays — one or more arrays to compare against. You can pass as many as you like.
  • $value_compare_func — a callback that compares two values. It must return an integer less than, equal to, or greater than 0 when the first argument is considered respectively less than, equal to, or greater than the second — the same contract used by usort() and the spaceship operator (<=>).

It returns a new array of the surviving key/value pairs from $array. The callback is always the last argument.

How comparison works

An entry from the first array is kept unless another array has both the same key (compared internally as strings) and a value the callback reports as equal (returns 0). In other words:

  • Keys → strict, built-in comparison (the assoc in the name).
  • Values → your callback (the u, for user-defined).

This is the key difference from array_diff_assoc(), which compares values with (string) casting, and from array_udiff(), which ignores keys entirely.

Basic example

<?php

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

$array1 = array("a" => "red", "b" => "green", "c" => "blue");
$array2 = array("a" => "red", "b" => "blue", "c" => "green");

$result = array_udiff_assoc($array1, $array2, "compareArrays");

print_r($result);

?>

Walking through it key by key:

  • a"red" vs "red": keys match, callback returns 0 (equal) → removed.
  • b"green" vs "blue": keys match, values differ → kept.
  • c"blue" vs "green": keys match, values differ → kept.

So the output is:

Array
(
    [b] => green
    [c] => blue
)

Comparing against several arrays

You can pass more than one array to compare against. An entry survives only if it is missing from every other array. Here the callback compares strings by length first, then alphabetically:

<?php

function compareValues($a, $b) {
  return strlen($a) <=> strlen($b) ?: strcmp($a, $b);
}

$current  = ["item1" => "apple", "item2" => "banana", "item3" => "kiwi"];
$baseline = ["item1" => "apple", "item2" => "cherry", "item3" => "kiwi"];

$result = array_udiff_assoc($current, $baseline, "compareValues");

print_r($result);

// Array
// (
//     [item2] => banana
// )

Only item2 differs: "banana" (6 letters) and "cherry" (6 letters) are the same length, so the callback falls through to strcmp(), which reports them as different. item1 and item3 are identical in both arrays and are dropped.

Comparing objects

The real strength of array_udiff_assoc() shows when values are objects or arrays — things you can't compare with a plain string cast. The callback decides what "equal" means. Here two carts are compared by price only, ignoring the product name:

<?php

class Product {
  public function __construct(public string $name, public float $price) {}
}

function byPrice(Product $a, Product $b): int {
  return $a->price <=> $b->price;
}

$cart = [
  "p1" => new Product("Pen", 1.50),
  "p2" => new Product("Notebook", 3.00),
];

$reference = [
  "p1" => new Product("Pen", 1.50),
  "p2" => new Product("Notebook", 4.25),
];

$diff = array_udiff_assoc($cart, $reference, "byPrice");

foreach ($diff as $key => $product) {
  echo "$key => {$product->name} ({$product->price})\n";
}

// p2 => Notebook (3)

p1 has the same price in both carts and is removed; p2's price changed, so it survives.

Gotchas

  • The callback is the last argument, not the second. A common mistake is calling array_udiff_assoc($a, $callback, $b). The order is always: first array, then the arrays to compare against, then the callback.
  • The callback compares values, not keys. Keys are handled internally with strict comparison; you cannot influence key matching here. If you need a custom key comparison too, reach for array_udiff_uassoc().
  • Return an integer, not a boolean. Returning true/false from the callback works by accident (they cast to 1/0) but is fragile — return the result of <=> or an explicit -1/0/1.
  • The result keeps the original keys from the first array; it does not reindex.

When to use it

Reach for array_udiff_assoc() when both the key and a custom value comparison matter — for example, diffing two keyed datasets of objects, comparing records case-insensitively while keeping their identifiers, or computing what changed between a previous and current state. If keys don't matter, use array_udiff(); if your values are simple scalars, the lighter array_diff_assoc() is usually enough.

Conclusion

array_udiff_assoc() is a precise tool for finding differences between arrays when both keys and custom value logic matter. By combining strict key matching with a comparison callback you control, you can diff complex data structures — objects, nested arrays, normalized strings — without writing nested loops or manual checks.

Practice

Practice
What does the 'array_udiff_assoc()' function in PHP do?
What does the 'array_udiff_assoc()' function in PHP do?
Was this page helpful?