Arrays7 min readExamples run on PHP 8.5.10

array_uintersect_uassoc()

Learn how array_uintersect_uassoc() intersects arrays using one callback for values and another for keys, with PHP 8.4 examples, edge cases and mistakes.

Signature

array_uintersect_uassoc(
    array $array1,
    array ...$arrays,
    callable $value_compare_func,
    callable $key_compare_func
): array

Purpose

array_uintersect_uassoc() keeps the entries of the first array that also appear in every other array. An entry counts as shared only when both its key and its value match. You decide what "match" means: one callback compares values and a second callback compares keys.

This is useful when the built-in comparison rules is too rigid. Examples include case-insensitive keys, values that are equal after normalization, or objects compared by one property.

Signature

Parameters

  • array1: the array whose entries may be returned. Its keys are preserved in the result.
  • arrays: one or more further arrays to compare against. An entry must be found in all of them.
  • value_compare_func: receives two values and returns an integer that is less than, equal to, or greater than zero. Zero means "considered equal".
  • key_compare_func: receives two keys and follows the same return convention.

The two callbacks come last, after all the arrays. Neither has a default; both are required.

Return value and failures

The function returns an array holding the entries of array1 whose key and value are matched in every other array. If nothing is shared, the result is an empty array. Original keys from array1 are kept, and the other arrays only influence which entries survive.

A callback that is not callable raises a TypeError. The function does not return false on failure.

Example 1: the classic case-insensitive intersection

Using strcasecmp for both callbacks makes "b" match "B" and "green" match "GREEN".

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

The "red" entry is dropped because it has key 0 in the first array, while in the second array "red" sits at key 2. Keys must match as well as values.

Example 2: different rules for keys and values

The callbacks are independent. Here values are compared ignoring case, but keys must be identical.

Example
<?php
$a = ["x" => "Apple", "y" => "Pear", "z" => "Plum"];
$b = ["x" => "APPLE", "Y" => "PEAR", "z" => "plum"];
$result = array_uintersect_uassoc($a, $b, "strcasecmp", "strcmp");
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
{"x":"Apple","z":"Plum"}

The "y" entry is rejected because "y" and "Y" differ under strcmp, even though the values match ignoring case.

Example 3: three arrays and custom closures

With several arrays, an entry must be matched in each of them. This example treats numbers as equal when their absolute values are equal. The comparator includes a string fallback so it remains defined for non-numeric arguments during internal ordering.

Example
<?php
$a = ["a" => -1, "b" => 2, "c" => 3];
$b = ["a" => 1, "b" => 5, "c" => -3];
$c = ["a" => 1, "b" => 2, "c" => 3, "d" => 4];
$result = array_uintersect_uassoc(
    $a,
    $b,
    $c,
    fn($x, $y) => (is_numeric($x) && is_numeric($y))
        ? abs($x) <=> abs($y)
        : strcmp((string) $x, (string) $y),
    fn($x, $y) => $x <=> $y
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
{"a":-1,"c":3}

Key "b" fails because 2 has no match in the second array, where the value is 5. The result keeps the original value -1 from the first array, not the 1 seen elsewhere.

Edge cases

  • Callback order is not guaranteed. Each array is sorted internally before comparison, so your callback may receive any value from any array in any order. It must work for every pair, not just "value from array 1 versus value from array 2".
  • Consistent ordering matters. Because sorting is involved, a comparison that is not consistent (for example, a loose tolerance check) can produce surprising results.
  • Return integers. If a callback returns a float, PHP casts it to an integer. Values such as 0.1 and 0.99 both become 0, which means "equal". Use <=> instead of subtracting floats.
  • Duplicates in the first array. Entries are kept per key, so each qualifying key stays in the result with its own value.
  • Mixed types. If arrays contain strings, integers and nested arrays, the callback must handle all of them without warnings.

Common mistakes

  1. Putting the callbacks first. Both callbacks go after the arrays, with the value callback before the key callback.
  2. Swapping the two callbacks. A value comparator applied to keys (or the reverse) gives wrong matches without any error.
  3. Assuming only values matter. If you only need to compare values, use array_uintersect(). This function also requires keys to match.
  4. Returning booleans. A callback that returns $a == $b yields true or false, which is cast to 1 or 0. That is not a valid ordering. Return an integer from <=>, strcmp() or a similar function.
  5. Expecting values from the other arrays. The result always contains the array1 entries.
  • array_uintersect(): compares values with a callback; keys are ignored.
  • array_intersect_assoc(): compares keys and values with built-in string comparison.
  • array_intersect_uassoc(): built-in value comparison, callback for keys.
  • array_uintersect_assoc(): callback for values, built-in key comparison.

Recap

array_uintersect_uassoc() returns the entries of the first array whose key and value both match in all other arrays. You supply two comparison callbacks, value first and key second, and both must return integers. Keys of the first array are preserved, and callbacks should be consistent and able to handle any pair of values.

Tested examples

Classic case-insensitive intersection
<?php
$array1 = ["a" => "green", "b" => "brown", "c" => "blue", "red"];
$array2 = ["a" => "GREEN", "B" => "brown", "yellow", "red"];
$result = array_uintersect_uassoc($array1, $array2, "strcasecmp", "strcasecmp");
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
{"a":"green","b":"brown"}
Different rules for keys and values
<?php
$a = ["x" => "Apple", "y" => "Pear", "z" => "Plum"];
$b = ["x" => "APPLE", "Y" => "PEAR", "z" => "plum"];
$result = array_uintersect_uassoc($a, $b, "strcasecmp", "strcmp");
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
{"x":"Apple","z":"Plum"}
Three arrays with custom closures
<?php
$a = ["a" => -1, "b" => 2, "c" => 3];
$b = ["a" => 1, "b" => 5, "c" => -3];
$c = ["a" => 1, "b" => 2, "c" => 3, "d" => 4];
$result = array_uintersect_uassoc(
    $a,
    $b,
    $c,
    fn($x, $y) => (is_numeric($x) && is_numeric($y))
        ? abs($x) <=> abs($y)
        : strcmp((string) $x, (string) $y),
    fn($x, $y) => $x <=> $y
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
{"a":-1,"c":3}