W3docs

Utiliser array_udiff_uassoc en PHP

Apprenez à utiliser array_udiff_uassoc en PHP pour calculer la différence entre deux ou plusieurs tableaux avec des fonctions de comparaison personnalisées.

array_udiff_uassoc() calcule la différence entre deux ou plusieurs tableaux en vérifiant à la fois les clés et les valeurs — et vous laissez décider comment les deux sont comparés en fournissant deux callbacks personnalisés. Un élément du premier array est conservé dans le résultat seulement si aucun autre array ne contient un élément qui lui correspond à la fois sur la clé et sur la valeur, selon vos callbacks.

Cette page explique précisément comment les deux callbacks interagissent (la partie que la plupart des docs de référence passent sous silence), présente un exemple exécutable et montre quand cette fonction est le bon outil par rapport à ses équivalents plus simples.

Qu'est-ce que array_udiff_uassoc ?

array_udiff_uassoc() retourne les entrées de $array1 qui ne sont présentes dans aucun des autres tableaux. Contrairement à array_diff(), qui compare les valeurs uniquement par conversion en string, cette variante vérifie les clés et les valeurs ensemble et délègue les deux comparaisons à des fonctions fournies par l'utilisateur — c'est ce que signifient les deux u dans le nom (udiff = comparaison de valeur utilisateur, uassoc = comparaison de clé utilisateur).

La signature est :

Syntaxe de la fonction PHP array_udiff_uassoc

array_udiff_uassoc(
    array $array1,
    array $array2,
    array ...$arrays,        // one or more additional arrays
    callable $value_compare_func,
    callable $key_compare_func
): array

Les deux callbacks sont toujours les deux derniers arguments, dans cet ordre : la comparaison de valeur en premier, la comparaison de clé en second. Tout ce qui les précède est un array. Le résultat est un nouvel array des entrées de $array1 qui survivent à la comparaison, avec leurs clés d'origine préservées.

Comment la correspondance fonctionne réellement. Pour chaque entrée de $array1, PHP parcourt les autres tableaux à la recherche d'une entrée dont la clé est « égale » selon $key_compare_func et dont la valeur est « égale » selon $value_compare_func. Si une telle correspondance existe dans un autre array, l'entrée est supprimée ; sinon elle est conservée. Une entrée n'est supprimée que lorsque les deux comparaisons rapportent l'égalité.

Comprendre les fonctions de comparaison

Chaque callback reçoit deux arguments et doit retourner un entier, exactement comme un comparateur de tri :

  • Retourner 0 lorsque les deux éléments sont considérés égaux.
  • Retourner un entier positif lorsque le premier est « plus grand ».
  • Retourner un entier négatif lorsque le premier est « plus petit ».

PHP ne se préoccupe que de savoir si la valeur de retour est 0 (égal) ou non, mais un résultat à trois voies cohérent est nécessaire car la fonction trie en interne. L'opérateur vaisseau spatial <=> est le moyen le plus simple d'en écrire un :

$value_compare_func = fn($a, $b) => $a <=> $b;   // strict ordering
$key_compare_func   = fn($a, $b) => strcasecmp((string) $a, (string) $b); // case-insensitive keys

Comme vous définissez les deux comparaisons, vous pouvez faire des choses que les fonctions de diff intégrées ne peuvent pas — par exemple, traiter les clés sans tenir compte de la casse, ou comparer des objets selon une seule propriété.

Exemple : utilisation de base

<?php

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

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

$array1 = array('a' => 'apple', 'b' => 'banana', 'c' => 'cherry', 'd' => 'durian');
$array2 = array('a' => 'apple', 'b' => 'game', 'c' => 'cherry');
$array3 = array('a' => 'apple', 'b' => 'door', 'c' => 'cherry', 'g' => 'durian');

$result = array_udiff_uassoc($array1, $array2, $array3,  'compare_values', 'compare_keys');

print_r($result);

?>

Ici compare_values et compare_keys sont de simples comparateurs à trois voies. L'appel effectue le diff de $array1 par rapport à $array2 et $array3, en ne conservant que les entrées dont la clé et la valeur ne correspondent nulle part ailleurs. La sortie est :

Array
(
    [b] => banana
    [d] => durian
)

Voici pourquoi chaque entrée survit ou est supprimée :

  • a => apple — supprimée : $array2 (et $array3) possède la même clé a et la même valeur apple.
  • b => bananaconservée : les autres tableaux utilisent la clé b, mais leurs valeurs sont game / door, pas banana. Les valeurs diffèrent, donc aucune correspondance n'est trouvée.
  • c => cherry — supprimée : correspondance trouvée dans les deux autres tableaux.
  • d => durianconservée : $array3 contient la valeur durian, mais sous la clé g, pas d. Les clés diffèrent, donc aucune correspondance n'est trouvée.

Ce dernier cas illustre tout l'intérêt de la fonction : même si la valeur durian existe ailleurs, la clé ne correspond pas, donc l'entrée est conservée. Un diff basé uniquement sur les valeurs comme array_udiff() l'aurait supprimée.

Exemple : clés insensibles à la casse

Comme la comparaison de clés vous appartient, vous pouvez ignorer la casse des clés tout en comparant les valeurs de manière stricte :

<?php

$wanted  = ['x' => 10, 'y' => 20, 'z' => 30];
$current = ['x' => 10, 'Y' => 20, 'z' => 99];

$result = array_udiff_uassoc(
    $wanted,
    $current,
    fn($v1, $v2) => $v1 <=> $v2,                       // values: strict ordering
    fn($k1, $k2) => strcasecmp((string) $k1, (string) $k2) // keys: case-insensitive
);

print_r($result);

Sortie :

Array
(
    [z] => 30
)

x => 10 et y => 20 sont supprimés (current possède la même valeur sous une clé qui correspond de manière insensible à la casse), tandis que z => 30 survit parce que current a z => 99 — la clé correspond mais la valeur 99 !== 30.

Quand l'utiliser (et quoi utiliser à la place)

Utilisez array_udiff_uassoc() seulement lorsque vous avez besoin d'une logique personnalisée pour les deux, clés et valeurs. Si vous en avez moins besoin, un équivalent plus simple est plus rapide à lire et à écrire :

Vous devez contrôler…Utilisez
Les valeurs uniquement (callback), clés ignoréesarray_udiff()
Les valeurs (callback) + clés avec ===array_udiff_assoc()
Les clés (callback) + valeurs avec ===array_diff_uassoc()
Aucune — diff de valeur simplearray_diff()

Pièges courants

  • Ordre des arguments. Les callbacks sont les deux derniers arguments, la comparaison de valeur en premier. Les passer dans le mauvais ordre produit silencieusement des résultats erronés plutôt qu'une erreur.
  • Au moins deux tableaux. Vous devez passer $array1, au moins un autre array, et ensuite les deux callbacks — cinq arguments minimum.
  • Retourner un int, pas un bool. Retourner true/false depuis un comparateur fonctionne par accident (ils sont convertis en 1/0) mais casse l'ordre. Utilisez <=> ou un -1/0/1 explicite.
  • Les clés sont préservées. Le résultat conserve les clés d'origine de $array1 ; il n'est pas réindexé.

Si les callbacks sont nouveaux pour vous, consultez PHP Callback Functions, et pour une remise à niveau sur les tableaux en général, PHP Arrays.

Conclusion

array_udiff_uassoc() est la plus flexible des fonctions de différence de tableaux de PHP : elle compare les entrées à la fois sur la clé et sur la valeur, et confie les deux comparaisons à vos propres callbacks. Une entrée du premier array survit seulement si aucun autre array ne lui correspond sur les deux dimensions. Utilisez-la lorsque les règles de comparaison intégrées (===, conversion en string) ne sont pas suffisantes — par exemple pour des clés insensibles à la casse, des valeurs tenant compte de la locale, ou la comparaison d'objets par un champ — et revenez à une variante array_diff* plus simple lorsque vous n'avez pas besoin de ce niveau de contrôle.

Pratique

Pratique
Quelle est la fonctionnalité de la fonction array_udiff_uassoc en PHP ?
Quelle est la fonctionnalité de la fonction array_udiff_uassoc en PHP ?
Was this page helpful?