Quand on instancie une classe avec l'opérateur new un espace mémoire est attribué à l'instance de l'objet créé. Cet espace mémoire est construit par une méthode particulière qui s'appelle un constructeur.

Dans PHP, il existe également un destructeur qui est une méthode particulière appelée juste avant que l'objet ne soit supprimé de la mémoire.

Constructeur

Un constructeur sert essentiellement à initialiser les valeurs des attributs d'un nouvel objet lors de l'instanciation de sa classe.

Un constructeur peut être implicite ou explicite. Bien que dans 99% des classes le constructeur soit explicite, nous commencerons par rapidement voir ce qu'est un constructeur implicite.

Constructeur implicite

Un constructeur implicite est un constructeur qui n'est pas défini par le concepteur de la classe. Dans le code de la classe on ne trouvera aucune méthode particuliére qui serait invoquée lors de l'instanciation.

Dans le cas d'un constructeur implicite, si les attributs n'ont pas de valeur assignée lors de leur définition, ils ont par défaut la valeur NULL.

Si la classe a un constructeur implicite, les parenthèses qui suivent son nom lors de son instanciation sont facultatives : $objet = new Classe est équivalent à $objet = new Classe().

Exemple : constructeur implicite

Constructeur explicite

Un constructeur explicite est une méthode magique qui s'appelle __construct(). Si cette méthode __construct est définie explicitement dans le code de la classe, elle sera invoquée automatiquement par PHP lors de l'instanciation de la classe avec l'opérateur new.

La méthode constrcuteur __construct() accepte généralement un ou plusieurs paramètres qui vont servir à initialiser la valeur d'attributs de la classe pour caractériser l'instance du nouvel objet.

Si le constructeur explicite n'a pas de paramètre, les parenthèses qui suivent le nom de la classe lors de son instanciation sont facultatives. On peut écrire $objet = new Classe.

Si le constructeur explicite accepte des paramètres, les parenthèses qui suivent le nom de la classe lors de son instanciation sont obligatoires. Il FAUT écrire $objet = new Classe().

Avec PHP, il n'est pas possible (comme en Java par exemple) de surcharger un constructeur.

Exemple : constructeur explicite

Validation des paramètres

Si on passe des paramètres au constructeur, ceux-ci doivent être validés avant d'être affectés comme valeur à des attributs.

Si des setters sont implémentés pour les attributs, ils doivent être appelés depuis le constructeur pour effectuer la mise à jour de la valeur de l'attribut.

S'il n'y a pas de setter pour les attributs, la validation doit être faite dans le constructeur.

L'exemple suivant est une classe Livre avec des attributs titre, auteur, nombre de pages, prix et catégorie. Les valeurs de ces attributs sont validées dans le constructeur, sauf pour le prix qui a un setter.

Exemple : validation des paramètres du constructeur

Paramètres dans un tableau

ASTUCE : quand un constructeur (ou une méthode ou une fonction) acceptent un grand nombre de paramètres, il est pratique d'utiliser un tableau pour passer ces paramètres.

Le plus pratique est d'utiliser un tableau associatif. On peut ainsi nommer les paramètres, les passer dans n'importe quel ordre et facilement en ajouter de nouveaux.

Exemple : paramètres dans un tableau associatif

Bien que d'un usage moins pratique, on peut aussi utiliser un tableau à index numérique.
L'exemple suivant instancie des guitares avec les informations trouvées dans un fichier texte référençant nos guitares en vente. Le fichier s'appelle guitares.txt et se trouve dans le dossier stock.
Le contenu du fichier est le suivant :

Guild D120|639|6
Fender Villager|444|12
Gibson Hummingbird|2033|6
Ibanez PCBE12-OPN|229|4
Epiphone EJ-200CE|334|6
Gretsch Falcon|599|12

On trouve le même genre de formattage que celui utilisé dans la page sur la lecture de fichiers.

On considère que les informations trouvées dans le fichier sont valides et on ne fait donc pas de vérifications dans le constructeur de la classe Guitare.

Exemple : paramètres dans un tableau index numérique

Destructeur

De la même façon qu'il y a une méthode magique __construct() invoquée automatiquement par PHP lors de l'instanciation d'une classe, il existe une autre méthode magique __destruct() qui, si elle est définie, sera invoquée automatiquement par PHP lors qu'un objet sera supprimé de la mémoire car il n'existe plus aucune référence à l'objet.

La méthode __destruct() de PHP est l'équivalent de la méthode finalize() en Java.

La méthode __destruct() n'accepte pas de paramètre. Si on la définit avec un ou des arguments, le script n'est pas exécuté et s'arrête avec une erreur fatale.

L'exemple suivant montre une classe Stock qui contient les objets Guitare de notre stock.
Quand on détruit l'instance de Stock ($stock = null;) observez les appels de destructeurs : le destructeur de l'objet Stock est d'abord invoqué, puis comme il n'existe plus de référence aux objets Guitare leur destructeur est à leur tour invoqué.

Exemple : destructeur

Exercice : constructeur explicite

la classe Livre

Reprenez la classe Livre de l'exercice précédent et faites les tests de validité en appelant les setters dans le constructeur.

Les modifications suivantes doivent être apportées :
- si une ou des valeurs passées au constructeur ne sont pas valides, un message d'erreur doit être affiché sans que le script soit arrêté,
- si une des valeurs passées au constructeur n'est pas valide, le nouvel objet est supprimé.
Le message d'erreur affiché doit être de la forme 'Valeur [valeur passée] invalide pour l'attribut [nom attribut].'

Vous devez tester votre code en instanciant des Livre avec les informations suivantes qui provoqueront toutes des erreurs :

Titre Auteur Nb Pages Prix Cat.
Pas de titre 70 17 Méthode
Pas d'auteur 160 4.90 Méthode
Mauvais nombre de pages Mauvais prix 0 -21.90 Partition
Seulement le titre OK inconnu 30 euros Magazine
affichage obtenu

Une solution possible

Exercice : constructeur implicite

Exercice : tableau de paramètres

L'exercice consiste à instancier des Livre suivant la classe simplifiée ci-contre avec les informations trouvées dans notre base de données exemple pour MySQL.
On a supprimé les setters de la classe car on considère que les informations provenant de la base de données sont correctes et n'ont pas besoin d'être validées.

la classe Livre
schéma de la base de données php_tuto

Pour que l'exemple fonctionne, il faut bien sûr que la base de donnée de test php_tuto soit toujours installée sur votre serveur MySQL. N'oubliez pas d'inclure la bibliothéque bib_params.php pour les paramètres de connexion.

Les informations à passer au constructeur se trouvent dans la table livres et dans la table auteurs. Tous les livres de la table livres seront affichés triés par titre. Le tableau retourné par la fonction mysqli_fetch_assoc() sera passé tel quel au constructeur.

affichage obtenu

Une solution possible

Exercice : tableau de paramètres

Exercice : destructeur

Réalisez une classe BDD (base de données, très simpliée, voire simpliste) avec une méthode destucteur qui ferme la base de données quand l'objet base de donnée est supprimé.
Comme pour l'exercice précédent, on utilisera notre base de données exemple pour MySQL.

schéma de la base de données php_tuto

Pour que l'exemple fonctionne, il faut bien sûr que la base de donnée de test php_tuto soit toujours installée sur votre serveur MySQL. N'oubliez pas d'inclure la bibliothéque bib_params.php pour les paramètres de connexion.

Le constructeur n'a pas de paramètre. Il réalise la connexion avec les constantes BD_SERVEUR, BD_USER, BD_PASS, BD_NOM. Si la connexion n'est pas possible, la méthode stopper() est appelée avec le message "Pas de connexion".

La méthode lire() a un seul paramètre : la requête SELECT à envoyer à la base. Pour simplifier, on ne fera pas de test de validité pour s'assurer qu'on a bien une requête SELECT.
Si cette requête provoque une erreur, la méthode stopper() est appelée avec le message "Erreur requête".
Les enregistrements sélectionnés par la requête sont renvoyés par la méthode sous la forme d'un tableau d'enregistrements (ie un tableau de tableaux).

La méthode stopper() a un seul paramètre : le texte d'un message d'erreur. Le message d'erreur est affiché puis le script est arrêté.

Le destructeur ferme la base de données avec la fonction mysqli_close(). Pour contrôler que le destructeur est bien appelé, il affichera "Fin du destructeur BDD".

Le script doit afficher la liste des auteurs (nom et prénom) contenus dans la table auteurs.

la classe BDD
affichage obtenu

Une solution possible

Exercice : destructeur