Apprendre à coder sur pierre-giraud.com

DES COURS COMPLETS ET GRATUITS POUR TOUS

SOMMAIRE

Introduction

  1. Présentation du cours
  2. Introduction au PHP
  3. Mettre en place un env. de travail

Les bases en PHP

  1. Syntaxe de base du PHP
  2. Premières instructions PHP
  3. Introduction aux variables PHP
  4. Types de valeurs et concaténation
  5. Opérations sur les variables
  6. Conditions et opérateurs de comparaison
  7. Les conditions if, if...else et if... elseif... else
  8. Utilisation avancée des conditions
  9. Structures ternaires et switch
  10. Les boucles PHP
  11. Découverte des fonctions
  12. La portée des variables
  13. Les constantes PHP
  14. Les variables tableaux PHP
  15. Tableaux associatifs
  16. Tableaux multidimensionnels
  17. Test n°1

Gestion des dates en PHP

  1. Le timestamp
  2. Obtenir et formater une date
  3. Tester la validité d'une date
  4. Test n°2

Opérations sur les fichiers en PHP

  1. Lire, ouvrir, fermer un fichier
  2. Parcourir et lire un fichier par partie
  3. Créer un fichier et écrire dedans
  4. Ecrire dans un fichier
  5. Les instructions include et require
  6. Test n°3

Les variables superglobales

  1. Découverte des variables superglobales
  2. Les cookies
  3. Les sessions
  4. Test n°4

Les expressions régulières et PHP

  1. Découverte des regex
  2. Les fonctions PHP PCRE
  3. Quantifieurs et options
  4. Classes de caractères
  5. Test n°5

L'orienté objet en PHP

  1. Classes, instances et objets
  2. Propriétés et méthodes
  3. Extension de classe et héritage
  4. Le principe d'encapsulation
  5. La méthode constructeur
  6. L'opérateur de résolution de portée et la surcharge
  7. Constantes, méthodes et propriétés statiques
  8. Les classes et méthodes abstraites
  9. Les interfaces
  10. Les méthodes magiques
  11. Le chainage de méthodes
  12. Test n°6

Notions avancées en POO

  1. Le typage explicite
  2. Les traits
  3. Les closures et les classes anonymes
  4. L'auto-chargement des classes
  5. Le mot clef final
  6. Résolution statique à la volée
  7. Parcourir des objets
  8. Le clonage d'objets
  9. Comparaison d'objets
  10. Test n°7

Filtres, erreurs et exceptions

  1. Introduction aux filtres
  2. Utilisation pratique des filtres
  3. Gérer les erreurs en PHP
  4. Gérer les exceptions en PHP

COMPARER DES OBJETS EN PHP

Problématique et limites de la comparaison d'objets

La comparaison d’objets est différente de la comparaison de variables classiques.

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 si ils font référence à la même instance de la même classe.

Comparer des objets : exemple pratique

Illustrons cela avec un exemple :

On commence par créer une classe de support pour nos objets

On compare nos objets grâce aux opérateurs et comparaison simple et d'identité

Pour cet exemple, on simplifie notre classe Humain qui ne contient plus qu’un constructeur servant à donner une valeur à notre propriété $nom.

Dans notre script principal, on commence par créer trois objets $pierre, $pierre2 et $victor à partir de notre classe. On créé également une variable objet $pierre3 qui va stocker la même chose que $pierre (je reparlerai de cela à la fin de ce chapitre).

Ensuite, on créé une fonction bool2str() (« booléen vers chaine de caractères ») qui va accepter un booléen en argument et retourner la valeur « FAUX » si le booléen à l’entrée était false ou « VRAI » dans le cas où on lui passe le booléen true. Cela nous permettra d’être plus clair par la suite.

Finalement, on crée une fonction compareObjets() qui va avoir pour rôle de comparer nos différents objets. Cette fonction a donc besoin de deux paramètres pour fonctionner qu’on appelle ici $o1 et $o2 et qui vont représenter les objets qui vont être comparés.

Le code de la fonction en soi est assez simple à comprendre : on utilise les opérateurs de comparaison de valeur et d’identité et le résultat renvoyé par le PHP à l’issue de la comparaison (true ou false) est passé en argument à bool2str.

Il ne nous reste plus qu’à comparer effectivement notre variable objet $pierre à nos autres variables objets et à commenter les résultats.

Résultat de notre comparaison d'objets

On commence ici par comparer $pierre à $pierre2 en valeur. Les deux variables objets sont bien égales en valeur puisque ce sont bien des instances de la même classe qui possèdent les mêmes attributs et valeurs associées (la propriété $nom possède la même valeur « Pierre » dans chacun des deux cas).

En revanche, les deux variables ne passent pas le filtre de la comparaison en identité puisqu’on a bien créé deux instances différentes de la classe Humain.

Concernant les deux objets $pierre et $victor, ce sont deux instances différentes de la même classe qui définissent une valeur différente pour la propriété $nom : ils sont donc différents en valeur (et de fait en identité).

Finalement, on observe que $pierre3 et $pierre sont égaux en valeur et en identité. En effet nous n’avons pas créé de nouvelle instance de la classe Humain pour créer $pierre3 : cette variable correspond tout simplement à une « copie » de $pierre.

Identifiants, pointeurs et références : la théorie

Ci-dessus, vous pouvez voir que j’ai parlé d’identifiant pointant vers le même objet et de copie d’objet. J’aimerais revenir sur ces points.

Ce que je vais tenter d’expliquer maintenant n’est pas évident à saisir car il va s’agir là de notions avancées sur le fonctionnement profond de l’orienté objet en PHP.

Si vous ne saisissez pas bien ce qui va suivre, très honnêtement, ce ne sera probablement pas pénalisant pour la suite de votre carrière de développeur. Cependant, il est toujours mieux selon moi de bien comprendre les choses !

En PHP, on a l’habitude de dire que les objets sont passés par référence par défaut. Cela signifie qu’on ne travaille pas directement sur l’objet en soi mais sur un alias de l’objet.

Cependant, ce n’est plus exactement vrai aujourd’hui. Depuis le PHP 5, une variable objet ne contient plus l’objet en soi, mais seulement un identifiant d’objet qui va permettre aux accesseurs d’objets (nos fameux « getters ») de trouver cet objet.

Ainsi, lorsqu’on utilise une variable objet en tant qu’argument, ou qu’on retourne une variable objet via une fonction, ou encore qu’on l’assigne à une autre variable (comme on l’a fait plus haut avec $pierre et $pierre3), nos différentes variables ne sont pas des références directes à notre objet mais ne contiennent que des copies de l’identifiant qui pointent vers le même objet.

Identifiants, pointeurs et références : la pratique

Concrètement, qu’est-ce que cela change ? Regardons l’exemple ci-dessous pour bien comprendre (je place ici ma classe dans le même fichier pour plus de simplicité) :

Illustration du passage par référence et identifiant en PHP

Passage par référence et copie d'identifiat d'objets en PHP

Ce que vous devez bien comprendre dans cet exemple, c’est que les références ou alias partagent toujours le même destin puisqu’ils partagent et représentent la même chose. Notez par ailleurs qu’on utilise le signe & en PHP pour passer un argument par référence à une fonction ou pour indiquer qu’on souhaite créer une référence.

Passer des arguments à une fonction par référence permet à la fonction de modifier la valeur des arguments en soi (par défaut, les arguments sont passés par valeur en PHP et leur valeur ne peut donc pas être modifiée directement par la fonction.

En revanche, lorsqu’on créé des copies du même identifiant, les opérations vont se passer un peu différemment. Si on modifie une valeur d’une copie, alors la valeur de l’autre sera également modifiée comme pour les alias.

Cependant, si on affecte un nouvel identifiant à notre copie, cela ne modifiera pas les autres variables contenant l’identifiant vers le premier objet, à la différence des alias.

Une nouvelle fois, on touche ici à des notions relativement complexes et abstraites, donc pas d’inquiétude si vous n’avez pas bien compris : cela ne vous pénalisera pas pour le reste du cours et vous pourrez toujours revenir là-dessus plus tard à tête reposée.

Chapitre précédent

Chapitre suivant