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
): arrayLes 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_funcet 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
0lorsque 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 keysComme 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éaet la même valeurapple.b => banana— conservée : les autres tableaux utilisent la cléb, mais leurs valeurs sontgame/door, pasbanana. Les valeurs diffèrent, donc aucune correspondance n'est trouvée.c => cherry— supprimée : correspondance trouvée dans les deux autres tableaux.d => durian— conservée :$array3contient la valeurdurian, mais sous la clég, pasd. 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ées | array_udiff() |
Les valeurs (callback) + clés avec === | array_udiff_assoc() |
Les clés (callback) + valeurs avec === | array_diff_uassoc() |
| Aucune — diff de valeur simple | array_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 unbool. Retournertrue/falsedepuis un comparateur fonctionne par accident (ils sont convertis en1/0) mais casse l'ordre. Utilisez<=>ou un-1/0/1explicite. - 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.