W3docs

Understanding PHP's array_udiff() Function

Learn how PHP's array_udiff() compares arrays using a user-defined callback and returns values found only in the first array. Examples with numbers and objects.

array_udiff() computes the difference between arrays by comparing their values with a callback function that you supply. It returns the values present in the first array that are not found in any of the other arrays. The "u" in the name stands for user-defined — unlike array_diff(), which compares values as strings, array_udiff() lets you decide exactly when two values count as "equal".

This page covers the function's syntax, how the callback works, runnable examples with numbers and objects, and the common gotchas to watch for.

When would you use array_udiff()?

Reach for array_udiff() whenever the default comparison in array_diff() is too crude:

  • Objects. array_diff() converts each value to a string. Objects without a __toString() method cannot be compared that way, so you need a callback that inspects a property instead.
  • Custom equality. You want a case-insensitive comparison, a comparison by a single field, or a tolerance-based numeric comparison.
  • Mixed or normalized data. You want to treat "5", 5, and 5.0 as the same value, or compare floats with rounding.

If you only need plain string comparison, prefer the simpler array_diff().

How array_udiff() works

The function takes two or more arrays, with the last argument being the comparison callback. It returns an array of the values from the first array that the callback does not find equal to any value in the later arrays. Keys and order from the first array are preserved.

Syntax

array_udiff(array $array1, array $array2, array ...$arrays, callable $value_compare_func): array
  • array $array1 — the array whose values are returned (the "base" array).
  • array $array2 — an array to compare against.
  • array ...$arrays — any number of additional arrays to compare against.
  • callable $value_compare_func — the comparison callback. It is always the last argument.

The comparison callback

The callback receives two values and must return an integer:

  • a number less than 0 if the first value is "smaller",
  • 0 if the two values are considered equal,
  • a number greater than 0 if the first value is "larger".

Returning 0 is what marks two values as equal, so a value in $array1 is excluded from the result whenever the callback returns 0 for it against some value in a later array. The < 0 / > 0 results let PHP sort the values internally for an efficient comparison — getting them right matters, so don't just return 0 or 1. The spaceship operator (<=>) is the easiest correct way to produce this value.

Example 1: comparing two arrays of numbers

This example uses a named function as the callback to find numbers that are in $array1 but not in $array2:

<?php

function compare_numbers($a, $b) {
    if ($a == $b) {
        return 0;
    } elseif ($a < $b) {
        return -1;
    } else {
        return 1;
    }
}

$array1 = [1, 2, 3, 4, 5];
$array2 = [2, 4, 6];

$result = array_udiff($array1, $array2, 'compare_numbers');

print_r($result);

?>

compare_numbers() returns 0 whenever two values match, so the matching numbers (2 and 4) are removed. The result keeps the original keys from $array1:

Array
(
    [0] => 1
    [2] => 3
    [4] => 5
)

The whole callback could be replaced with a one-liner using the spaceship operator: fn($a, $b) => $a <=> $b.

Example 2: comparing arrays of objects

This is the case array_diff() cannot handle. Here we compare two arrays of Product objects by their id, returning the products that are not in the second list:

<?php

class Product {
    public function __construct(public int $id, public string $name) {}
}

$catalog = [
    new Product(1, 'Keyboard'),
    new Product(2, 'Mouse'),
    new Product(3, 'Monitor'),
];

$discontinued = [
    new Product(2, 'Mouse'),
];

$available = array_udiff(
    $catalog,
    $discontinued,
    fn(Product $a, Product $b) => $a->id <=> $b->id
);

foreach ($available as $product) {
    echo $product->id . ': ' . $product->name . PHP_EOL;
}

?>

This prints the products whose id is not present in $discontinued:

1: Keyboard
3: Monitor

Because the callback compares only the id, the differing name values are irrelevant — the comparison logic is entirely yours to define.

Things to keep in mind

  • The callback is always the last argument, no matter how many arrays you pass.
  • array_udiff() compares values. To compare by both keys and values, use array_udiff_assoc(); to compare keys with a callback too, use array_udiff_uassoc().
  • Return a proper three-way result (negative / 0 / positive), not just 0 or 1. PHP relies on the ordering to compare efficiently, and a sloppy callback can produce wrong results.
  • The result preserves the keys and order of $array1. Call array_values() if you want a re-indexed array.
  • Only values from the first array can appear in the output — values unique to the later arrays are never returned.

Practice

Practice
What is the purpose of array_udiff() function in PHP?
What is the purpose of array_udiff() function in PHP?
Was this page helpful?