Cette solution est valable à partir de la version 4 de php.
L'énumération est un mécanisme de synonymie entre un ensemble de valeurs constantes et un ensemble de noms de variables d'un même espace de noms.
Le mécanisme de synonymie le plus classique est celui de la constante. Les langages qui acceptent ce mécanisme permettent de déclarer et d'utiliser un nom, généralement en visibilité globale, à la place d'une valeur scalaire qui ne sera pas modifiée au cours du temps d'exécution d'un programme.
En php, on écrira :
define ("maConstante" , 5.5);
et pour faire un test de valeur, on écrira quelque chose comme :
if ($maVariable === maConstante)
faireAvec();
else
faireAutrement();
Les constantes sont le moyen le plus simple de simuler une énumération. Mais aussi le moins puissant.
Par exemple, si on doit manipuler une liste de noms de systèmes d'exploitation, on pourrait déclarer :
define ("Linux" , 0); define ("Mac" , 1); define ("Windows" , 2);
Ainsi lorsqu'on veut faire un test de valeur sur une variable de ce type, on écrira :
switch ($maVariable) { case Linux : faireAvecLinux(); break; case Mac : faireAvecMac(); break; case Windows : faireAvecWindows(); break; }
Ce qui est plus lisible que :
switch ($maVariable) { case 0 : faireAvecLinux(); break; case 1 : faireAvecMac(); break; case 2 : faireAvecWindows(); break; }
Cette solution ravira les plus désoeuvrés, mais ne contentera pas les plus exigeants. En effet, dans une liste de constantes, les noms ne sont pas reliés ensemble au sein d'un même groupe et peuvent même être déclarés séparément dans le code source. Ils sont juste placés côte à côte par commodité.
Maintenant lorsqu'on a un ensemble de valeurs constantes qui ont une signification commune, il est plus commode de les regrouper dans un même espace de noms qui ont un sens du point de vue de la lisibilité du programme.
Cette solution est valable à partir de la version 4 de php.
La grande force des tableaux en php, c'est que derrière chaque tableau se cache un tableau associatif. Le tableau traditionnel associe des entiers consécutifs à des valeurs d'un certain type, le tableau associatif associe des valeurs d'un type arbitraire à des valeurs d'un autre type. C'est une forme de généralisation de la notion de tableau.
En général, on déclare un tableau associatif de cette manière :
<?php $array = array( 1, 1, 1, 1, 1, 8=>1, 4=>1, 19, 3=>13); print_r($array); ?>
L'exemple ci-dessus va afficher :
Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 13
[4] => 1
[8] => 1
[9] => 19
)
Pour créer une énumération, on procèdera ainsi :
$OS = array ("Linux"=>0, "Mac"=>1, "Windows"=>3);
Et pour faire un test de valeur, on écrira :
switch ($maVariable) { case $OS["Linux"] : faireAvecLinux(); break; case $OS["Mac"] : faireAvecMac(); break; case $OS["Windows"] : faireAvecWindows(); break; }
On fait ici une utilisation moins courante du tableau d'association, puisqu'on utilise les chaînes de caractères comme clés de recherche dans le tableau et les indices comme valeurs du tableau. Mais cette forme de langage permet de préciser deux choses :
Noter que la version courte, bien que tentante, ne fonctionnera pas :
$OS = array ("Linux", "Mac", "Windows");
Puisque le préprocesseur php attribuera automatiquement les indices, c'est l'équivalent de :
$OS = array (0=>"Linux", 1=>"Mac", 2=>"Windows");
Hors l'astuce utilisée ici se sert de la clé d'association comme élément de langage.
Cette solution n'est utilisable qu'à partir de la version 5 de php.
La classe est une unité de programmation qui représente un concept manipulé par le programme. Il est commode de disposer d'énumérations relatives à une classe ou un concept. Ce qui permet de rendre toujours plus lisible et compréhensible un programme.
Cette solution n'en est pas vraiment une, mais plutôt une extension de la solution précédente, à la programmation objet.
Avec la version 4 de php qui inclut la première, les concepts de programmation objet, on pourrait déclarer le tableau $OS dans une classe conteneur, mais il en deviendrait membre et serait répliqué inutilement avec toutes les instances de la classe conteneur. Ce n'est qu'avec la version 5 de php, qui intègre la notion de membre de classe statique, que l'astuce suivante pourra être utilisée.
Par exemple, si le programme opère des transactions avec le système sur lequel il est installé, on pourra créer une classe System :
class System { public static $OS = array("Linux"=>0, "Mac"=>1, "Windows"=>3); public static $LinuxFamily = array("debian"=>0, "suze"=>1, "ubuntu"=>3); private $name; private $family; private $version; /* Constructeur */ public __construct($name, $family, $version) { $this->name = $name; $this-> family = $family; $this->version = $version; } /* Accesseur */ public function getName() { return $this->name; } ... }
et pour déclarer une variable du type System, on écrira :
$monSysteme = new System(System::$OS["Linux"], System::$LinuxFamily["ubuntu"], "7.10");
Ce qui est forcément plus lisible que :
$monSysteme = new System(0, 3, "7.10");
De la même manière, pour faire un test de valeur, on écrira :
switch ($monSysteme->getName()) { case System::$OS["Linux"] : faireAvecLinux(); break; case System::$OS["Mac"] : faireAvecMac(); break; case System::$OS["Windows"] : faireAvecWindows(); break; }
Ce document vous a présenté trois techniques qui permettent de pallier à l'absence de la notion d'énumération dans le langage php. Elle ne sont pas très élégantes, mais elles permettent au moins d'apporter plus de lisibilité au code.
Quelques faiblesses de ces techniques :
Il s'agit juste de solutions temporaires, en attendant que les développeurs de php intègrent enfin cette notion au langage...
Il faut savoir être patient, le langage java n'intègre cette notion que depuis la version 5 (mais avec brio puisque la notion d'énumération est complètement intégrée à la notion de classe).