Arrays7 min readExamples run on PHP 8.5.10

array_diff_assoc()

Learn how PHP array_diff_assoc() finds entries whose key and value pair is missing from other arrays, with examples, edge cases and common mistakes.

Signature

array_diff_assoc(array $array, array ...$arrays): array
Available since PHP 4.3.07.48.08.18.28.38.48.5All versions →

Purpose

array_diff_assoc() answers the question: which entries of this array do not appear, with the same key, in any of these other arrays? It is the key-aware sibling of array_diff(). Plain array_diff() looks only at values, so a value that exists anywhere in the other arrays is removed. array_diff_assoc() removes an entry only when both the key and the value match an entry in another array.

Typical uses include finding which settings a user changed from the defaults, detecting modified fields in a record, and checking what differs between two associative snapshots.

Signature

Parameters and defaults

  • $array: the array to compare from. Only entries from this array can appear in the result.
  • ...$arrays: zero or more arrays to compare against. An entry from $array is kept only if no other array contains the same key with an equal value.

There are no other defaults. Since PHP 8.0 the function may be called with just one argument; in that case nothing is compared against, so you get back all of the entries of $array.

Return value and failure cases

The function returns an array holding the entries of $array that are not present in any of the other arrays. Keys are preserved exactly as they were in $array, so the result may have gaps or string keys. There is no false return for a failed comparison; an empty array simply means nothing differed. If you pass something that is not an array, PHP throws a TypeError.

How values are compared

Two values are treated as equal only when their string representations are identical, in other words (string) $a === (string) $b. This is stricter than ==, so "00" and 0 are different, but it is looser than === on types, so the integer 14 and the string "14" count as the same. Keys are compared as PHP array keys, which means "1" and 1 are already the same key.

Example 1: the manual-style color arrays

The entry "a" => "green" exists in both arrays, so it disappears. The unkeyed "red" in the first array gets key 0, while in the second array key 0 already belongs to "yellow", so "red" there lives at key 1. The key-and-value pair 0 => "red" therefore has no match and stays.

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

Example 2: string comparison of values

Because values are compared as strings, 0 and "00" do not match, while 2 and "2" do.

Example
<?php
$first = [0, 1, 2];
$second = ["00", "01", "2"];
echo json_encode(array_diff_assoc($first, $second), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[0,1]

Example 3: changed settings and argument order

Here the saved settings are compared with the defaults. The font value 14 equals "14" as a string, so it is not reported as a change. Swapping the arguments reports the default side of the difference instead. Adding a third array removes any entry that the third array also contains.

Example
<?php
$saved = ["theme" => "dark", "lang" => "en", "font" => 14];
$defaults = ["theme" => "light", "lang" => "en", "font" => "14"];
$override = ["theme" => "dark"];
echo json_encode(array_diff_assoc($saved, $defaults), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_diff_assoc($defaults, $saved), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_diff_assoc($saved, $defaults, $override), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"theme":"dark"}
{"theme":"light"}
[]

Edge cases

  • Preserved keys: the result keeps original keys. Use array_values() on the result if you need a zero-based list.
  • One-sided result: entries that exist only in the other arrays are never reported. The comparison is not symmetric.
  • Single argument: array_diff_assoc($data) returns the same entries as $data.
  • Empty arrays: comparing an empty first array always gives an empty result; comparing against empty arrays removes nothing.
  • String conversion quirks: null converts to an empty string, so null and "" under the same key are considered equal. The float 1.0 becomes "1" and matches "1".
  • Depth: only one dimension is checked. If a value is itself an array, it is not compared recursively, and converting it to a string produces a warning. Compare nested levels yourself, for example by calling the function on $a["child"] and $b["child"].

Common mistakes

  1. Wrong argument order. The first array is the one being filtered. Passing the older array first reports the old values rather than the new ones.
  2. Expecting a two-way diff. If you need entries that differ in either direction, call the function twice with swapped arguments and merge the results with care for key collisions.
  3. Using array_diff() for records. array_diff() ignores keys, so a value that moved to a different field is not detected.
  4. Assuming strict typing. 14 and "14" are equal here. If type differences matter, you need a callback-based function such as array_udiff_assoc().
  5. Relying on list positions. For unkeyed arrays, keys are positions, so inserting one item at the start makes many later entries look different.
  • array_diff() compares values only.
  • array_diff_uassoc() compares keys with your own callback.
  • array_udiff_assoc() compares values with a callback and keys normally.
  • array_udiff_uassoc() uses callbacks for both values and keys.
  • array_intersect_assoc() returns the entries that do match by key and value.

Recap

Use array_diff_assoc() when a key and its value together define identity. Put the array you care about first, remember that values are compared as strings, expect preserved keys in the result, and do not expect it to look inside nested arrays.

Tested examples

Color arrays where only matching key and value pairs are removed
<?php
$current = ["a" => "green", "b" => "brown", "c" => "blue", "red"];
$other = ["a" => "green", "yellow", "red"];
echo json_encode(array_diff_assoc($current, $other), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"b":"brown","c":"blue","0":"red"}
Values are compared as strings
<?php
$first = [0, 1, 2];
$second = ["00", "01", "2"];
echo json_encode(array_diff_assoc($first, $second), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[0,1]
Changed settings, argument order and multiple comparison arrays
<?php
$saved = ["theme" => "dark", "lang" => "en", "font" => 14];
$defaults = ["theme" => "light", "lang" => "en", "font" => "14"];
$override = ["theme" => "dark"];
echo json_encode(array_diff_assoc($saved, $defaults), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_diff_assoc($defaults, $saved), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_diff_assoc($saved, $defaults, $override), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"theme":"dark"}
{"theme":"light"}
[]