10- Les références

Les données que l’on stock en mémoire sont stockées dans des espaces mémoires auxquels nous avons besoin d’assigner une étiquette : la référence. Les références de PHP sont différentes de celles que l’on peut trouver dans d’autres langages (le C++ par exemple), et ce dont il est question ici ne concerne que le PHP.

En PHP, les références sont simplement des alias de variables qui les rendent utilisables sans les copier et qui permettent de modifier directement les paramètres d’une fonction sans les retourner. Par exemple si une méthode a les références de deux variables en paramètre et qu’elle les modifie, elle peut simuler un return des deux paramètres sans rien retourner puisque la portée des variables est devenue globale car on n’a pas transmis une copie des variables mais directement l’adresse qui les modifie.

Pour utiliser la référence d'une variable en PHP (comme dans d'autres langages), il faut précéder le nom de la variable de &. Par exemple, pour utiliser la référence de $a, on écrira &$a.

En général, les références permettent également de gagner du temps et de la mémoire en évitant de copier systématiquement les variables des paramètres des fonctions si l’on veut directement agir dessus. Néanmoins, le fonctionnement des références en PHP étant très différent de celui du C, cela n'est pas vrai dans tous les cas et peut simplement indiquer que l'on va modifier ou non une variable dans uen fonction ou une itération.

Exemple :

$a = 2;
function add(int &$nombre){
   $nombre += 5;
}
add($a);
var_dump($a);//a vaut 7

Dans le cas des structures itérables : Il est également possible d’utiliser les références dans boucles, notamment foreach, pour éviter de copier toutes les variables et clés du tableau itéré. Néanmoins, il n’y a pas de réel gain de performance à l’utilisation des références en PHP pour itérer sur une structure, puisque la structure itérée n’est pas copiée si elle n’est pas modifiée.

Exemple d’itération sur un array en foreach sans référence :

function getThings(array $thingsTab) : array
{
   $retTab = [];
   foreach ($thingsTab as $key => $thing){
       $retTab[] = $thing->doSomething();
   }
   return $retTab;
}

Dans l’exemple suivant, nous faisons exactement la même chose sauf que nous modifions directement l’array grâce au passage par référence.

Exemple d’itération sur un array en foreach avec références :

function getThings(array $thingsTab) : array
{
   foreach ($thingsTab as $key => &$thing){
       $thing->doSomething();
   }
   return $thingsTab;
}

Dans ce cas, nous n’avons pas besoin de déclarer un deuxième array à remplir avec les modifications apportées au premier. Nous aurions également pu passer l’array par référence dans la méthode pour éviter de le retourner, mais cela est moins lisible car nous avons un type de retour “void”.

Beaucoup de décisions dans les choix de ce style dépendent de la lisibilité et de la simplicité du code, plus que de la performance, et c’est donc à la discrétion de chacun.

Exemple d’itération sur un array passé par référence en foreach avec références :

function getThings(array &$thingsTab) : void
{
   foreach ($thingsTab as $key => &$thing){
       $thing->doSomething();
   }
}