Les variables dynamiques en PHP

Aujourd’hui, j’ai eu envie de vous parler d’une notion php très utile, mais pourtant peu connue : les variables dynamiques (aussi appelées « les variables variables »). Cette notion m’a sauvée la vie à plusieurs reprises au cours de ces dernières années !

Qu’est-ce qu’une variable dynamique ?

Une variable dynamique, c’est tout simplement une variable dont le nom est… dynamique. C’est-à-dire que son nom est affecté et utilisé dynamiquement, selon les besoins du script.

Une variable dynamique peut être déclarée de deux manières :

$temp  // variable "classique"
$$temp // 1ère écriture de la variable dynamique
${$temps} // 2ème écriture de la variable dynamique

Voici un exemple tiré de la documentation officielle de php :

$a = 'bonjour';
$$a = 'monde';
echo "$a ${$a}"; // retourne "bonjour monde"
echo "$a $bonjour"; // retourne également "bonjour monde"

Je ne sais pas pour vous, mais personnellement cela ne me parait pas très clair, et j’ai du mal à voir l’intérêt d’une telle notion avec un tel exemple. Rassurez-vous, je vais de ce pas vous présenter un exemple bien plus concret. Vous verrez, vous comprendrez tout de suite beaucoup mieux l’intérêt des variables variables 😉

Exemple concret d’utilisation des variables dynamiques

Vous le savez peut-être, j’ai créé il y a quelques années un jeu de gestion de centre équestre, nommé Equid’Expérience. Je développe régulièrement de nouvelles fonctionnalités sur ce jeu, et il y a quelques semaines j’ai eu besoin des variables dynamiques. C’est d’ailleurs ce qui m’a donné envie d’écrire cet article 😉

Le contexte

La demande initiale : ajouter un système permettant aux joueurs d’acheter des chevaux créés aléatoirement.

La problématique : les compétences du cheval doivent être générées dynamiquement en fonction de la race du cheval. Sur les 7 compétences existantes, chaque cheval généré aura des points dans seulement 3 d’entre elles. (Note : pour l’exemple, je n’utiliserai que 5 des 7 compétences).

Le point de départ : grâce à un autre script, j’ai déjà les 3 compétences principales de chaque race :

// Compétences de la race A :
print_r($bestSkills);
// Retour : Array ( [0] => dressage [1] => jumping [2] => reining ) 


// Compétences de la race B :
print_r($bestSkills);
// Retour : Array ( [0] => reining [1] => coupling [2] => racing ) 

Je sais donc dans quelles compétences attribuer des points à chacune des races. Pour cela, il y a plusieurs manières de procéder, en voici 2 :

Solution 1 : la multitude de « if »

La première méthode consiste à recourir à une multitude de « if » :

$coupling = $reining = $dressage = $jumping = $racing = 0; // initialisation des compétences

// Grâce à la fonction in_array(), je vérifie si la compétence est dans la liste qui nous intéresse ou non
if (in_array('coupling', $bestSkills)) $coupling = 10;
if (in_array('reining', $bestSkills)) $reining = 10;
if (in_array('dressage', $bestSkills)) $dressage = 10;
if (in_array('jumping', $bestSkills)) $jumping = 10;
if (in_array('racing', $bestSkills)) $racing = 10;

Je n’ai ensuite plus qu’à hydrater mon objet Horse avec les différentes compétences. Comme j’avais initialisé les variables, celles qui n’étaient pas dans le tableau sont égales à 0. Les autres ont la valeur 10.

$Horse = new Horse(array(
     'coupling' => $coupling,
     'reining' => $reining,
     'dressage' => $dressage,
     'jumping' => $jumping,
     'racing' => $racing
));

// Race 1 : 
var_dump($Horse); 
// Retour : object(Horse)#1 (5) { ["coupling":"Horse":private]=> int(0) ["reining":"Horse":private]=> int(10) ["dressage":"Horse":private]=> int(10) ["jumping":"Horse":private]=> int(10) ["racing":"Horse":private]=> int(0) }


// Race 2 : 
var_dump($Horse); 
// Retour : object(Horse)#1 (5) { ["coupling":"Horse":private]=> int(10) ["reining":"Horse":private]=> int(10) ["dressage":"Horse":private]=> int(0) ["jumping":"Horse":private]=> int(0) ["racing":"Horse":private]=> int(10) }

Solution 2 : utiliser des variables dynamiques

Là encore, je commence par initialiser mes variables de compétences :

$coupling = $reining = $dressage = $jumping = $racing = 0;

Ensuite, je parcours le tableau de mes compétences, et j’applique à chacune d’elle les points que je veux leur attribuer (dans mon exemple, ce sera 10 points). Pour cela, j’utilise une variable dynamique.

foreach ($bestSkills as $skill) {
     $$skill = 10;
}

Je n’ai ensuite plus qu’à hydrater mon objet Horse de la même manière que dans la première solution. J’obtiendrai bien évidemment le même résultat.

Comparatif des deux méthodes

Les deux méthodes fonctionnent parfaitement. Mais, comme vous l’aurez remarqué, la première méthode est bien plus fastidieuse. Elle nécessite en effet davantage de lignes de code, à raison d’une par compétence.

En utilisant les variables dynamiques, peu importe le nombre de compétences : le code ne sera pas plus long. Que j’ai 3 variables ou 300, pas la peine d’écrire une ligne de plus ! Un sacré confort pour le développeur, n’est-ce pas ? 😉

Mise en garde

Attention, les variables dynamiques restent une notion très sensible. En effet, elles peuvent potentiellement écraser d’autres noms de variables, et ainsi entraîner des problèmes parfois conséquents. Utilisez-les donc avec précaution, de préférence en les isolant dans une méthode dans laquelle il n’est pas possible d’usurper des variables.

Dans de nombreux cas, les tableaux peuvent être une solution alternative plus sûre : pensez-y !

Néanmoins, comme nous venons de le voir, dans certaines situations les variables dynamiques sont réellement très utiles.

Et vous ? Avez-vous déjà eu recours aux variables dynamiques ? Dans quels cas ?

Catégorie : Programmation
Publié le 28/08/2019

Poster un commentaire