Arrays7 min readExamples run on PHP 8.5.10

array_uintersect_assoc()

Learn how array_uintersect_assoc() intersects arrays by exact key and by a custom value comparison callback, with PHP 8.4 examples and pitfalls.

Signature

array_uintersect_assoc(array $array, array ...$arrays, callable $value_compare_func): array

Purpose

array_uintersect_assoc() keeps the entries of the first array that also appear in every other array. An entry counts as shared only when two conditions hold:

  1. The key is the same in every array. Keys are compared strictly, with no callback involved.
  2. The value is considered equal by a comparison function that you supply.

The u in the name means a user callback decides value equality. The assoc part means keys take part in the match. Compare it with array_uintersect(), which ignores keys, and with array_intersect_assoc(), which checks keys but uses built-in string comparison for values.

Signature

Parameters

  • $array: the array whose entries are tested. Its keys and their order are what you get back.
  • ...$arrays: one or more arrays to compare against. An entry survives only if a matching key and equal value exist in all of them.
  • $value_compare_func: the last argument, and it has no default. It receives two values and must return an integer that is negative, zero or positive. Zero means the values are equal.

Return value and failures

The function returns a new array holding the entries of $array that are present in all other arrays. Keys are preserved, and the order of the first array is kept. If nothing matches, the result is an empty array.

Passing something that is not an array, or a callback that is not callable, raises a TypeError. The input arrays are never modified.

Example 1: case-insensitive values

The built-in strcasecmp works well as a callback. Note that the key b does not match B, because key comparison is exact.

Example
<?php
$a = ["a" => "green", "b" => "brown", "c" => "blue", "red"];
$b = ["a" => "GREEN", "B" => "brown", "yellow", "red"];
echo json_encode(array_uintersect_assoc($a, $b, "strcasecmp"), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"a":"green"}

Only a survives. red is at index 0 in the first array but at index 1 in the second, and index 0 of the second array holds yellow.

Example 2: several arrays and a custom callback

With more than two arrays, an entry must match in each one. Here numeric strings and integers are compared by their integer value.

Example
<?php
$first = ["apple" => "10", "pear" => "20", "fig" => "30"];
$second = ["apple" => 10, "pear" => 25, "fig" => 30];
$third = ["apple" => "10.0", "fig" => "30", "kiwi" => "5"];
$result = array_uintersect_assoc(
    $first,
    $second,
    $third,
    fn($x, $y) => (int) $x <=> (int) $y
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"apple":"10","fig":"30"}

pear fails because 20 differs from 25, and it is also missing from the third array. The returned values are the originals from the first array, so "10" stays a string.

Example 3: comparing records by a field

The callback can look inside nested values, for example to match records by id while ignoring other fields.

Example
<?php
$a = [
    0 => ["id" => 1, "n" => "A"],
    1 => ["id" => 2, "n" => "B"],
    2 => ["id" => 3, "n" => "C"],
];
$b = [
    0 => ["id" => 1, "n" => "x"],
    5 => ["id" => 2],
    2 => ["id" => 3],
];
$result = array_uintersect_assoc($a, $b, fn(array $x, array $y): int => $x["id"] <=> $y["id"]);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"0":{"id":1,"n":"A"},"2":{"id":3,"n":"C"}}

The record with id 2 is in both arrays, but at key 1 in one and key 5 in the other, so it is dropped. Because the surviving keys are 0 and 2, the JSON output is an object rather than a list.

Edge cases

  • Key normalization: PHP turns the string key "1" into the integer key 1 before the function sees it, so those two spellings always match. Other string keys are compared exactly, including case.
  • Callback order: the manual warns that each array is sorted internally before comparison. Your callback may therefore receive values from any array in any order, and it must handle every value type that can appear.
  • Float returns: the callback result is cast to an integer. Returning 0.5 or -0.4 is treated as 0, meaning equal. Use <=>, or return an explicit integer, instead of subtracting floats.
  • Empty result: no match gives [], not false or null.

Common mistakes

  • Expecting key comparison to use the callback. The callback sees values only. For custom key matching, look at array_uintersect_uassoc().
  • Placing the callback first. It must be the last argument.
  • Writing a callback that returns a boolean, such as fn($a, $b) => $a == $b. This returns true when equal, which casts to 1 and means "greater", the opposite of what you intended. Return $a <=> $b instead.
  • Assuming the result is re-indexed. Keys are preserved, so numeric gaps can appear.
  • Expecting values from the other arrays in the result. Only entries from the first array are returned.
  • array_uintersect(): callback value comparison, keys ignored.
  • array_intersect_assoc(): keys and values checked with built-in comparison.
  • array_intersect_uassoc(): callback for keys, built-in comparison for values.
  • array_uintersect_uassoc(): separate callbacks for values and keys.

Recap

Use array_uintersect_assoc() when entries must share the same key and have values that your own rule considers equal. Put the callback last and return a proper integer such as $a <=> $b. Expect keys and order to come from the first array, and keep the callback tolerant of any value type.

Tested examples

Case-insensitive value comparison with strcasecmp
<?php
$a = ["a" => "green", "b" => "brown", "c" => "blue", "red"];
$b = ["a" => "GREEN", "B" => "brown", "yellow", "red"];
echo json_encode(array_uintersect_assoc($a, $b, "strcasecmp"), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"a":"green"}
Three arrays with an integer-based callback
<?php
$first = ["apple" => "10", "pear" => "20", "fig" => "30"];
$second = ["apple" => 10, "pear" => 25, "fig" => 30];
$third = ["apple" => "10.0", "fig" => "30", "kiwi" => "5"];
$result = array_uintersect_assoc(
    $first,
    $second,
    $third,
    fn($x, $y) => (int) $x <=> (int) $y
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"apple":"10","fig":"30"}
Matching records by id at identical keys
<?php
$a = [
    0 => ["id" => 1, "n" => "A"],
    1 => ["id" => 2, "n" => "B"],
    2 => ["id" => 3, "n" => "C"],
];
$b = [
    0 => ["id" => 1, "n" => "x"],
    5 => ["id" => 2],
    2 => ["id" => 3],
];
$result = array_uintersect_assoc($a, $b, fn(array $x, array $y): int => $x["id"] <=> $y["id"]);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"0":{"id":1,"n":"A"},"2":{"id":3,"n":"C"}}