La comparaison d’objets PHP

Plus tôt dans ce cours nous avons appris à comparer différentes variables qui stockaient des valeurs simples (une chaine de caractères, un chiffre, un booléen, etc.).

On va également pouvoir comparer des variables objets de manière similaire, ce qui va pouvoir être très utile pour s’assurer par exemple qu’un objet est unique.

 

Principe de la comparaison d’objets

Pour comparer deux variables objets entre elles, nous allons à nouveau devoir utiliser des opérateurs de comparaison. Cependant, étant donné que les valeurs comparées vont cette fois-ci être des valeurs complexes (car un objet est composé de diverses propriétés et méthodes), nous n’allons pas pouvoir utiliser ces opérateurs de comparaison aussi librement que lors de la comparaison de valeurs simples.

La première chose à savoir est qu’on ne va pouvoir tester que l’égalité (en valeur ou en identité) entre les objets. En effet, cela n’aurait aucun sens de demander au PHP si un objet est « inférieur » ou « supérieur » à un autre puisqu’un objet regroupe un ensemble de propriétés et de méthodes.

En utilisant l’opérateur de comparaison simple ==, les objets vont être considérés comme égaux s’ils possèdent les mêmes attributs et valeurs (valeurs qui vont être comparées à nouveau avec == et si ce sont des instances de la même classe.

En utilisant l’opérateur d’identité ===, en revanche, les objets ne vont être considérés comme égaux que s’ils font référence à la même instance de la même classe.

 

Comparer des objets en pratique

Pour illustrer la façon dont le PHP va comparer différents objets et pour commenter les résultats renvoyés, nous allons nous baser sur l’exemple suivant :

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php
            class Utilisateur{
                protected $nom;
                public function __construct($n){
                    $this->nom = $n;
                }
                public function __clone(){
                    $this->nom = $this->nom. ' (clone)';
                }
                public function getNom(){
                    echo $this->nom;
                }
            }

            $pierre = new Utilisateur('Pierre');
            $pierre2 = new Utilisateur('Pierre');
            $jean = $pierre; 
            $victor = clone $pierre;
            
            echo 'Egalité simple entre $pierre et $pierre2 ? ';
            var_dump($pierre == $pierre2);
            echo '<br>Identité entre $pierre et $pierre2 ? ';
            var_dump($pierre === $pierre2);
            echo '<br><br>Egalité simple entre $pierre et $jean ? ';
            var_dump($pierre == $jean);
            echo '<br>Identité entre $pierre et $jean ? ';
            var_dump($pierre === $jean);
            echo '<br><br>Egalité simple entre $pierre et $victor ? ';
            var_dump($pierre == $victor);
            echo '<br>Identité entre $pierre et $victor ? ';
            var_dump($pierre === $victor);
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

Exemple de comparaison d'objets en PHP

Ici, on réutilise notre classe Utilisateur créée précédemment. Cette classe définit une propriété $nom ainsi qu’un constructeur qui va initialiser notre propriété, une méthode getNom() dont le rôle est de renvoyer la valeur de $nom de l’objet courant et une méthode __clone() qui va mettre à jour la valeur de la propriété $nom d’un clone.

On instancie ensuite deux fois notre classe Utilisateur et on stocke le résultat dans deux variables objet $pierre et $pierre2.

En dessous, on assigne le contenu de $pierre dans une nouvelle variable objet $jean. Je vous rappelle ici que nos deux objets contiennent deux copies d’un identifiant pointant vers le même objet (la même instance de la classe).

Finalement, on crée un clone de $pierre grâce au mot clef clone qu’on appelle $victor. Ici, une véritable copie de l’objet est créée et donc nos deux variable objets vont bien représenter deux instances différentes et indépendantes de la classe. Dès que le clonage est terminé, notre méthode __clone() est appelée et la valeur de $nom de $victor est mise à jour.

L’idée va alors ici être de comparer nos différents objets. Pour cela, on utilise les opérateurs de comparaison == et === qui renvoient 1 si la comparaison réussit ou 0 si la comparaison échoue. On passe la valeur renvoyée à la fonction var_dump() afin qu’elle nous renvoie le type de résultat (la valeur 1 correspond au booléen true tandis que 0 correspond à false.

La première comparaison simple entre $pierre et $pierre2 réussit. En effet, nos deux objets sont issus de la même classe et leur propriété $nom contient la même valeur puisqu’on a passé « Pierre » au constructeur dans les deux cas.

En revanche, la comparaison en termes d’identité échoue. La raison est que nos deux objets ont été créés en instanciant la classe à chaque fois et représentent donc deux instances différentes de la classe.

Cela n’est pas le cas pour notre objet $jean qui contient la copie d’un identifiant pointant vers le même objet (la même instance de la classe) que $pierre et qui va donc pouvoir être comparé à $pierre en termes d’identité avec succès.

Notre dernier objet, $victor, est un clone (ou une copie) de $pierre et stocke donc une instance différente de $pierre. De plus, juste après que le clonage ait été terminé, la valeur de $nom du clone a été mise à jour. La comparaison entre $victor et $pierre échoue donc à la fois en termes d’identité et en termes de comparaison simple.

Laisser un commentaire