Position actuelle: Accueil> Derniers articles> Pourquoi rencontrez-vous des difficultés avec array_diff ()? Quelles sont les meilleures alternatives pour résoudre ces problèmes?

Pourquoi rencontrez-vous des difficultés avec array_diff ()? Quelles sont les meilleures alternatives pour résoudre ces problèmes?

M66 2025-06-24

Dans PHP, Array_Diff () est une fonction très courante qui compare deux tableaux et renvoie des valeurs qui apparaissent dans le premier tableau mais pas dans d'autres tableaux. C'est idéal pour les tableaux unidimensionnels, mais lorsque vous essayez de l'utiliser pour faire face à des "tableaux de cou" (c'est-à-dire que les éléments du tableau sont toujours des tableaux), vous constaterez que les choses ne sont pas aussi simples que vous le pensez.

Comment fonctionne Array_Diff ()?

La définition officielle de Array_Diff () est de comparer les "valeurs" d'un tableau et de renvoyer ces "valeurs" qui existent dans le premier tableau mais pas dans d'autres tableaux. Donnons un exemple simple de tableau unidimensionnel:

 $a = ['apple', 'banana', 'cherry'];
$b = ['banana', 'dragonfruit'];

$result = array_diff($a, $b);
// s'avérer ['apple', 'cherry']

Ceci est très simple - ne comparez que les valeurs, quelles que soient les clés. Cependant, si nous utilisons à la place des tableaux imbriqués, le résultat sera différent.

Problèmes lors de la nidification des tableaux

Jetons un coup d'œil à l'exemple suivant:

 $a = [
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob']
];

$b = [
    ['id' => 2, 'name' => 'Bob']
];

$result = array_diff($a, $b);

Vous pouvez vous attendre à ce que $ le résultat revienne uniquement ['id' => 1, 'name' => 'Alice'] , mais vous obtiendrez en fait l'ensemble que $ A est retourné. En effet, PHP utilise == en interne pour comparer les valeurs lors de la comparaison des tableaux, et la méthode de comparaison des tableaux imbriqués n'est pas aussi "intelligent" que vous le pensez.

Lorsque Array_Diff () traite les tableaux dans un tableau, son mécanisme interne ne traite pas de manière récursive, mais traite l'ensemble du sous-réseau comme une "valeur" et essaie de se comparer avec le type de chaîne . Une fois que la structure du sous-réseau est légèrement incohérente (comme un ordre clé différent), il sera considéré comme des valeurs différentes, même si le contenu est exactement le même.

Meilleures alternatives

1. Personnaliser la fonction de définition de différence récursive

Afin de comparer correctement les tableaux imbriqués, nous pouvons écrire une fonction personnalisée pour comparer le contenu de l'élément de tableau par article:

 function array_diff_recursive($a, $b) {
    $diff = [];

    foreach ($a as $itemA) {
        $found = false;
        foreach ($b as $itemB) {
            if ($itemA == $itemB) {
                $found = true;
                break;
            }
        }
        if (!$found) {
            $diff[] = $itemA;
        }
    }

    return $diff;
}

$a = [
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob']
];

$b = [
    ['id' => 2, 'name' => 'Bob']
];

$result = array_diff_recursive($a, $b);
// retour [['id' => 1, 'name' => 'Alice']]

2. Utilisez Array_udiff () et la fonction de comparaison personnalisée

Array_udiff () vous permet de fournir une fonction de comparaison personnalisée, ce qui est particulièrement utile lors de la comparaison des structures complexes:

 function compare_nested_array($a, $b) {
    return $a == $b ? 0 : 1;
}

$result = array_udiff($a, $b, 'compare_nested_array');

Cette méthode vous permet de personnaliser la logique de comparaison, comme si vous vous souciez seulement de savoir si le champ ID correspond, que le nom soit le même.

3. Utilisez des valeurs de hachage (adaptées aux grands tableaux)

Si vous traitez une grande quantité de données, vous pouvez également générer un hachage pour chaque sous-réseau, puis les comparer avec le hachage:

 function get_hash($array) {
    return md5(json_encode($array));
}

$a_hashed = array_map('get_hash', $a);
$b_hashed = array_map('get_hash', $b);

$diff_keys = array_diff($a_hashed, $b_hashed);

$result = [];
foreach ($diff_keys as $key => $hash) {
    $result[] = $a[$key];
}

Cette technique convient aux scénarios avec de grands volumes de données. Il a non seulement de bonnes performances, mais peut également gérer des structures complexes.

Exemples de scénarios d'application

Par exemple, vous développez un service d'interface qui compare les différences entre deux listes d'autorisation des utilisateurs:

 $oldPermissions = [
    ['module' => 'user', 'access' => 'read'],
    ['module' => 'admin', 'access' => 'write'],
];

$newPermissions = [
    ['module' => 'user', 'access' => 'read'],
];

$removed = array_diff_recursive($oldPermissions, $newPermissions);
// Vous pouvez envoyer un e-mail à l'administrateur pour vous rappeler le changement des autorisations

Ou lorsque vous traitez des différences de version de configuration, vous pouvez également utiliser ces méthodes pour déterminer si l'élément de configuration est ajouté ou supprimé.

Conclusion

Bien que Array_Diff () soit très puissant lorsqu'il s'agit de tableaux simples, une fois qu'il entre dans une structure imbriquée, il semble sans scrupule. Heureusement, PHP fournit des outils puissants (tels que Array_udiff () , des fonctions personnalisées), et nous pouvons également répondre de manière flexible à des besoins spécifiques.

La rédaction d'une bonne logique de comparaison de tableau peut non seulement éviter les erreurs de données, mais également rendre le système plus stable. J'espère que vous pourrez utiliser ces techniques dans des projets réels pour rendre le code plus robuste!