Créer une classe en PHP
Date de publication : 28/10/2009
Par
Wes Shell (Auteur)
Joris Crozier (Traducteur)
Cet article est la traduction de
Class Design in PHP de Wes Shell, il parle des bonnes pratiques de la POO en PHP.
I. Introduction
II. Exercice
III. Continuons
IV. Liens
I. Introduction
Les classes sont le coeur de la programmation Objet en PHP. L'idée générale derrière la POO est de regrouper
les fonctions similaires au sein d'objets. Ces objets représentent des choses réelles comme des gens,
des lieux ou des choses. D'une certaine manière, si un programme était une phrase, tous les noms
de cette phrase seraient des objets.
Ex : Chat dans le Chapeau
Dans cet exemple, nous avons deux objets, Chat et Chapeau. Dans le but de construire une représentation
de ces objets nous allons utiliser le mot clef
class en PHP. (pour plus d'informations lisez
TODO)
class Chat { }
class Chapeau { }
|
Ces classes sont utilisées pour décrire nos objets. Le mot qui suit le mot clef class décrit un
genre d'objets que la classe représente. Nos classes représentent un Chat et un Chapeau. Pour créer
nos objets nous utilisons la syntaxe suivante :
Regardez le mot clef new. Cela précise à PHP que nous voulons crée un nouvel objet de type Chat.
Les parenthèses sont requises et invoquent le constructeur de la classe. Le constructeur est le code
qui est exécuté quand la classe créé un nouvel objet. Nous parlerons de la construction plus loin
dans cet article.
Techniquement ce code a créé un objet de type Chat. Cependant notre classe Chat est vraiment basique
et ne contient pas d'informations ou d'actions utiles. Dans le but de mieux décrire notre Chat nous
devons lui donner quelques propriétés. Les propriétés décrivent un objet comme les adjectifs décrivent
un nom.
class Chat
{
var $_couleur;
var $_race;
}
|
 |
Note : La bonne pratique fait nommer nos champs avec le préfixe _. Cela nous permet de vite nous
faire savoir que cette variable représente un champ de notre classe. Vous avez sûrement du voir des
gens utiliser les préfixes m_ et c_ pour représenter un 'membre' ou un 'champ'.
|
Ok donc nous avons quelques champs pour stocker les informations qui décrivent notre chat. Maintenant
nous devons protéger ces champs pour limiter la façon dont ils peuvent être accédées. Ces champs
sont comme notre ADN et sont très importants donc il est toujours de bon usage de contrôler la manière
d'y accéder.
Pour ce faire nous allons utiliser les mots clef 'public', 'private' et 'protected'. Par défaut tous
les champs sont 'public', ce qui veut dire qu'ils peuvent être accessibles depuis la classe ou depuis
l'extérieur de celle-ci. Ce peut être très mauvais car cela autorise vos champs à être manipulés
par n'importe qui. Cela tend à causer des erreurs de run-time inattendues.
'Protected' veut dire que les champs peuvent seulement être accessibles par les fonctions de la classe
ou celles des classes qui étendent celle-ci. Comme cet article ne traite pas de l'héritage et de
l'extension de classe nous ne parlerons pas de cette option.
'Private' est l'option la plus sécurisée. Cela veut dire que les champs peuvent seulement être accessibles
par les fonctions de la classe. C'est bien car vous pouvez contrôler quand et comment les informations
peuvent être modifiées ou accédées. Normalement c'est la meilleure option à choisir pour les champs
d'une classe et nous allons l'utiliser pour notre classe Chat.
class Chat
{
private $_couleur;
private $_race;
}
|
Maintenant nous avons besoin d'une méthode d'accès pour entrer des valeurs dans ces champs. Comme elles
sont en 'private' nous ne pouvons pas les configurer depuis l'extérieur de notre objet. Ce qui veut
dire que le code suivant provoquera une exception :
$monChat = new Chat();
$monChat->_couleur = "Vert";
|
Donc comment allons-nous entrer des valeurs dans ces champs. Dans notre cas la couleur est 'vert' et
la race est 'calico'. Pour ce faire nous allons utiliser notre constructeur de classe. Comme décrit
plus bas, le constructeur de classe est un bloc de code qui est exécuté quand la classe est instanciée
ou en utilisant le mot clef new.
Par défaut le constructeur est appelé pour créer une représentation de l'objet. Ce code est une part
du langage PHP et est exécuté chaque fois qu'une classe est instanciée. Instancier veut dire qu'une
instance de la classe est créée sous la forme d'un objet. On peut ajouter des instructions spéciales
à ce code en utilisant notre propre méthode _construct qui sera exécutée juste après le constructeur
par défaut.
class Chat
{
private $_couleur;
private $_race;
function __construct()
{
$this->_couleur = "Vert";
$this->_race = "Calico";
}
}
|
Aux regards du code précédent, vous devriez être en mesure de savoir ce qui se passe ici. La seule chose
qui peut différer est l'utilisation du mot clef 'this'. Cette variable spéciale est une référence
aux champs de l'objet. En gros nous configurons 'this' couleur du chat et 'this' race du chat. Maintenant
chaque fois que le constructeur sera exécuté les champs du chat seront configurés pour décrire celui-ci.
Ok, c'est génial, mais que faire si nous ne voulons pas que des chats calico verts. Nous voudrions plusieurs
chats différents. La réponse est facile. Comme n'importe quelle autre fonction, la fonction _construct
peut recevoir des valeurs en paramètres. Pour permettre une manière de décrire le chat au créateur
de l'objet, nous allons passer une variable pour la couleur et pour la race. Ensuite nous utiliserons
ces valeurs pour renseigner les champs de la classe Chat.
class Chat
{
private $_couleur;
private $_race;
function __construct($couleur, $race)
{
$this->_couleur = $couleur;
$this->_race = $race;
}
}
$monChat = new Chat("Vert","Calico");
|
Maintenant nous avons une méthode pour décrire les champs de notre chat, nous voulons une manière de
les récupérer pour que d'autres parties du programme puissent utiliser ces informations. Pour ce
faire nous utilisons des fonctions publiques au sein de la classe pour retourner les valeurs désirées.
Il y'a beaucoup de méthodes pour faire ceci et je vous encourage à toutes les étudier. La technique
que j'utilise simule le mieux la manière dont les propriétés marchent en C#, un langage fortement
typé.
Tout d'abord, nous devons déclarer une fonction pour tous les champs auxquels nous voulons accéder. Le
nom de la fonction doit décrire le champ auquel elle accède.
public function Couleur()
{
return $this->_couleur;
}
public function Race()
{
return $this->_race;
}
|
Quand ces méthodes sont appelées par nos objets, elles vont retourner les valeurs stockées dans nos champs
privés sécurisés. Maintenant nous pouvons partager la description de notre chat avec le reste du
monde.
$monChat = new Chat("vert","calico");
echo "Le chat " . $monChat->Couleur() . " " . $monChat->Race() . " peut s'assoire sur le grand chapeau rayé.";
|
Nous pouvons maintenant créer un chat avec une belle description et partager ces détails avec les autres.
Mais si nous voulons changer la description de ce chat. Nous pouvons utiliser les mêmes propriétés
pour autoriser l'utilisateur à changer ces valeurs. Le code pour le faire est présenté ci-dessous,
je vais expliquer ce qu'il se passe en m'appuyant sur cet exemple :
public function Couleur($value = "")
{
if ($value == "")
{
return $this->_couleur;
}
$this->_couleur = $value;
}
public function Race($value = "")
{
if ($value == "")
{
return $this->_race;
}
$this->_race = $value;
}
|
Regardez la partie du code que nous avons modifiée en commençant par le nom de la fonction. Nous avons
ajouté un attribut '$value' avec une valeur par défaut vide. Cela veut dire que si la fonction est
appelée sans paramètre, la valeur par défaut sera une chaîne vide.
Ensuite regardez le block if que nous avons ajouté. Précédemment nous retournions la valeur de nos champs
chaque fois que la propriété était appelée. Maintenant nous voulons retourner la valeur seulement
si aucune valeur n'est transmise à la propriété. La commande if vérifie si $value est une chaîne
vide. Si elle l'est, la propriété retourne la valeur actuelle du champ.
Si la valeur passée n'est pas vide, nous savons que nous devons changer la valeur actuelle du champ par
celle envoyée à la méthode. On procède de la même manière que dans le constructeur en utilisant le
mot clef 'this'. Maintenant si nous voulons changer des propriétés du chat nous pouvons le faire
depuis l'extérieur de la classe.
$monChat = new Chat("vert","calico");
echo "Le chat " . $monChat->Couleur() . " " . $monChat->Race() . " est assis sur le grand chapeau rayé.";
$monChat = new Chat("violet","calico");
echo "Le chat " . $monChat->Couleur() . " " . $monChat->Race() . " est assis sur le grand chapeau rayé.";
|
II. Exercice
Maintenant regardez si vous pouvez mettre en application ce que vous avez appris en essayent de compléter
la classe Chapeau. Pour vous aider à commencer je vais vous donner le nom des champs à utiliser dans
votre classe.
$_modele, $_taille
Le code complet :
class Chat
{
private $_couleur;
private $_race;
function __construct($couleur, $race)
{
$this->_ couleur = $couleur;
$this->_race = $race;
}
public function Couleur($value = "")
{
if ($value == "")
{
return $this->_couleur;
}
$this->_couleur = $value;
}
public function Race($value = "")
{
if ($value == "")
{
return $this->_race;
}
$this->_race = $value;
}
}
class Chapeau
{
private $_modele;
private $_taille;
function __construct($podele, $taille)
{
$this->_modele = $modele;
$this->_taille = $taille;
}
public function Modele($value = "")
{
if ($value == "")
{
return $this->_modele;
}
$this->_modele = $value;
}
public function Taille($value = "")
{
if ($value == "")
{
return $this->_taille;
}
$this->_taille = $value;
}
}
|
III. Continuons
Maintenant que nous avons nos objets Chat et Chapeau et leurs propriétés respectives, nous pouvons les
utiliser pour compléter la phrase.
$monChat = new Chat("vert","calico");
$monChapeau = new Chapeau("rayé","grand");
echo "Le chat " . $monChat->Couleur() . " " . $monChat->race() . " est assis sur le "
. $monChapeau ->Taille() . " chapeau " . $monChapeau ->Modele() . ".";
|
Donc vous vous dites que c'est génial, mais pourquoi faire tout ce travail alors que l'on pourrait le faire
avec un tableau associatif. Evidement il y a des bénéfices à utiliser des classes sinon cette option
n'existerait pas. Pour en savoir plus sur l'application de la POO en PHP veuillez lire l'article
sur la POO en PHP.
http://jcrozier.developpez.com/tutoriels/web/php/programmation-orientee-objet/
Une des forces des classes est leur capacité d'exécuter des actions aussi bien que tenir des informations
descriptives. Les actions qu'elles exécutent sont comme des verbes dans une phrase.
Ex : Le chat vert calico est assis sur le grand chapeau rayé.
Notre chat doit avoir la capacité de s'asseoir avant de pouvoir s'asseoir sur notre chapeau. Pour faire
ceci, nous allons créer une fonction dans notre classe pour exécuter cette action.
public function Asseoir() { }
|
Ensuite nous allons avoir besoin d'un champ supplémentaire pour savoir sur quoi le chat est assis. C'est
une bonne pratique de garder tout nos champs déclarés au même endroit au début de la description
de l'objet afin qu'ils soient facilement repérables plus tard. Retournons donc au début de notre
classe Chat, nous allons ajouter un nouveau champ appelé $_assis.
class Chat
{
private $_couleur;
private $_race;
private $_assis;
...
}
|
 |
Note : Les caractères ... dans l'exemple ci-dessus indiquent la suite du code que nous avons déjà décrite
précédemment.
|
Une autre bonne pratique est de commenter le champ qui stocke les références vers d'autres objets comme
ça vous et les autres savent à quoi va servir le champ sans avoir à parcourir tout le code. Maintenant
que nous avons une fonction Asseoir() et une place pour stocker sur quoi le chat est assis, nous
pouvons compléter notre fonction. Tout d'abord, nous allons ajouter un paramètre à la fonction pour
pouvoir passer sur quoi le chat va s'asseoir.
public function Asseoir($assis)
{
$this->_assis = $assis;
}
|
La fonction précédente s'explique d'elle-même. Quand elle est appelée, un objet 'assis' va être passé
et le champ $_assis va être configuré avec la référence de l'objet $assis. La fonction va marcher
dans l'état mais il y aura un petit problème. A cet instant nous sommes capables de configurer la
valeur du champ $_assis sans que ce soit un objet. Notre commentaire indique que nous attendons une
référence à un objet et non à une chaîne de caractères. Comme indiqué précédemment quand on parle
d'une propriété, nous pouvons contrôler comment notre champ est configuré. Pour ce faire nous devons
juste ajouter un peu de code à notre fonction.
public function Asseoir($assis)
{
if (!is_object($assis))
{
throw new Exception("Assis n'est pas un objet dans la fonction Asseoir().");
}
$this->_assis = $assis;
}
|
Maintenant si l'utilisateur de notre objet de classe essaie d'asseoir le chat sur quelque chose qui n'est
pas un objet, une exception sera levée stipulant qu'il ne peut pas faire ça. La dernière chose qu'il
reste à faire est de fournir une manière à l'application d'en savoir plus sur quoi notre chat est
assis. Pour ça nous devons créer une propriété pour notre assise. Comme nous voulons que l'utilisateur
puisse seulement configurer la valeur du siège en utilisant la propriété Asseoir(), la propriété
que nous allons créer ne permettra pas de changer cette valeur.
public function Siege()
{
return $this->_assis;
}
|
En combinant tout ceci notre classe finale devrait ressembler à ça :
class Chat
{
private $_couleur;
private $_race;
private $_assis;
function __construct($couleur, $race)
{
$this->_ couleur = $couleur;
$this->_race = $race;
}
public function Couleur($value = "")
{
if ($value == "")
{
return $this->_couleur;
}
$this->_couleur = $value;
}
public function Race($value = "")
{
if ($value == "")
{
return $this->_race;
}
$this->_race = $value;
}
public function Siege()
{
return $this->_assis;
}
public function Asseoir($assis)
{
if (!is_object($assis))
{
throw new Exception("Assis n'est pas un objet dans la fonction Asseoir().");
}
$this->_assis = $assis;
}
}
|
Maintenant notre chat possède une manière de s'assoir sur un objet et de faire savoir aux autres les
propriétés de sur quoi il est assis. En revenant à notre phrase originale, nous pouvons maintenant
remplacer tous les noms, les adjectifs et les verbes avec les informations de notre objet.
$monChat = new Chat("vert","calico");
$monChapeau = new Chapeau("rayé","grand");
$monChat ->Asseoir($monChapeau);
$monSiege = $monChat ->Siege();
echo "Le " . get_class($monChat). " " . $monChat ->Couleur() . " " . $monChat ->Race .
" est assis sur un" . $monSiege ->Taille() . " ". get_class($monSiege) . " ". $monSiege ->Modele() ;
|
La fonction get_class() est une fonction native de PHP qui retourne le nom de la classe responsable
de la création de l'objet. Dans notre cas l'objet $monChat a été créé par la classe Chat et l'objet
$monSiege a été créé par la classe Chapeau.
Bien que ce soit une application peu probable, le but est de vous montrer comment créer vos propres objets
de classe. Pour plus d'exemples de classes, d'objets et sur la manière d'utiliser les objets, veuillez
lire l'article
sur la POO en PHP.
class Chat
{
private $_couleur;
private $_race;
private $_assis;
function __construct($couleur, $race)
{
$this->_ couleur = $couleur;
$this->_race = $race;
}
public function Couleur($value = "")
{
if ($value == "")
{
return $this->_couleur;
}
$this->_couleur = $value;
}
public function Race($value = "")
{
if ($value == "")
{
return $this->_race;
}
$this->_race = $value;
}
public function Siege()
{
return $this->_assis;
}
public function Asseoir($assis)
{
if (!is_object($assis))
{
throw new Exception("Assis n'est pas un objet dans la fonction Asseoir().");
}
$this->_assis = $assis;
}
}
class Chapeau
{
private $_modele;
private $_taille;
function __construct($podele, $taille)
{
$this->_modele = $modele;
$this->_taille = $taille;
}
public function Modele($value = "")
{
if ($value == "")
{
return $this->_modele;
}
$this->_modele = $value;
}
public function Taille($value = "")
{
if ($value == "")
{
return $this->_taille;
}
$this->_taille = $value;
}
}
$monChat = new Chat("vert","calico");
$monChapeau = new Chapeau("rayé","grand");
$monChat ->Asseoir($monChapeau);
$monSiege = $monChat ->Siege();
echo "Le " . get_class($monChat). " " . $monChat ->Couleur() . " " . $monChat ->Race .
" est assis sur un" . $monSiege ->Taille() . " " . get_class($monSiege) . " ". $monSiege ->Modele() ;
|
IV. Liens


Copyright © 2009 Joris CROZIER. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.