Les références Qu'est ce qu'une référence ? En PHP, les références sont un moyen d'accéder au contenu d'une même variable en utilisant plusieurs noms. Les références ne sont pas comme des pointeurs en C : vous ne pouvez pas effectuer d'opération arithmétique de pointeurs sur celles-ci, ce ne sont pas des adresses mémoires, etc. Vous pouvez consulter pour plus d'informations. En fait, les références sont des alias dans la table des symboles. Notez qu'en PHP, le nom d'une variable et son contenu sont deux notions distinctes, ce qui fait que l'on peut donner plusieurs noms au même contenu. On peut faire l'analogie avec les fichiers sous Unix, et leur noms : les noms des variables sont les entrées dans un répertoire, tandis que le contenu de la variable est le fichier en lui-même. Les références en PHP peuvent alors être considérées comme semblables aux liens sous Unix. Que font les références ? Il existe trois principales utilisations des références : l'assignation par référence, le passage par référence, et le retour par référence. Cette section va introduire ces opérations, avec des liens vers plus de précisions. Assignation par référence Dans ce premier cas, les références PHP permettent de faire en sorte que deux variables référencent le même contenu. Par exemple : ]]> Cette écriture indique que $a et $b pointent sur le même contenu. $a et $b sont complètement égales ici : ce n'est pas $a qui pointe sur $b, ou vice-versa. Ce sont bien $a et $b qui pointent sur le même contenu. Si vous assignez, passez, ou retournez, une variable indéfinie par référence, elle sera créée automatiquement. Utilisation des références avec des variables indéfinies d); var_dump(property_exists($c, 'd')); // bool(true) ?> ]]> La même syntaxe peut être utilisée avec les fonctions qui retournent des références : ]]> Utiliser la même syntaxe avec une fonction qui ne retourne par référence génèrera une erreur, comme l'utiliser avec le résultat de l'opérateur new. Tant bien que les objets sont passés comme des pointeurs, ceci n'est pas identique au références comm expliqué dans la section les Objets et références. Si vous assignez une référence à une variable déclarée comme global dans une fonction, la référence ne sera visible qu'au sein de la fonction. Vous pouvez éviter cela en utilisant le tableau $GLOBALS. Référencer des variables globales depuis des fonctions ]]> Voyez global $var; comme un raccourci pour $var =& $GLOBALS['var'];. De ce fait, assigner une autre référence à $var modifie uniquement la référence locale de la variable. Si vous assignez une valeur à une variable qui a des références dans une structure &foreach;, les références seront également modifiées. Références et structure foreach ]]> Même si ce n'est pas strictement une assignation par référence, les expressions créées avec la structure de langage array() peuvent aussi se comporter comme telles, en préfixant par & l'élément du tableau. Voici un exemple : ]]> Notez par contre que les références à l'intérieur des tableaux peuvent s'avérer dangereuses. Utiliser une assignation normale (pas par référence) avec une référence à droite de l'opérateur ne transforme pas la partie gauche de l'assignation en référence, mais les références à l'intérieur des tableaux sont préservées. Ceci s'applique également aux appels de fonctions avec un tableau passé par valeur. Exemple : ]]> Autrement dit, d'un point de vue des références, le comportement des tableaux est défini élément par élément ; le comportement de chaque élément est indépendant du statut de référence du tableau qui les contient. Passage par référence Le deuxième intérêt des références est de permettre de passer des variables par référence. On réalise ceci en faisant référencer le même contenu par une variable locale à un fonction et par une variable du contexte appelant. Par exemple : ]]> Après l'exécution de cette portion de code, $a vaut 6. Cela provient du fait que, dans la fonction foo, la variable $var pointe sur le même contenu que $a. Pour plus d'informations à ce sujet, vous pouvez consulter la section passage par référence. Retour par référence Le troisième intérêt des références est de permettre le retour de valeurs par référence. Ce que les références ne sont pas Comme nous l'avons vu précédemment, les références ne sont pas des pointeurs. Cela signifie que le script suivant ne fera pas ce à quoi on peut s'attendre : ]]> Ici, la variable $var dans la fonction foo sera liée à $bar dans l'appelant, mais elle sera ensuite reliée à $GLOBALS["baz"]. Il n'est pas possible de lier $bar à quelque chose d'autre en utilisant le mécanisme de références, car $bar n'est pas accessible dans la fonction foo (certes, elle est représentée par $var, mais $var ne fait référence qu'à la valeur, et n'a pas de liaison dans la table de symboles de l'appelant). Vous pouvez utiliser le retour par référence pour référencer des variables sélectionnées par la fonction. Passage par référence Vous pouvez passer une variable par référence à une fonction, de manière à ce que celle-ci puisse la modifier. La syntaxe est la suivante : ]]> Il n'y a pas de signe de référence dans l'appel de la fonction, uniquement sur sa définition. La définition de la fonction en elle-même est suffisante pour passer correctement des arguments par référence. Les données suivantes peuvent être passées par référence : Une variable, comme dans foo($a) Une référence retournée par une fonction : ]]> Pour plus d'informations, voir les détails dans retour par référence. Toutes les autres expressions ne doivent pas être passées par référence, car le résultat sera indéfini. Par exemple, les passages par référence suivants sont invalides : ]]> Retourner des références Retourner des références est utile lorsque vous voulez utiliser une fonction pour déterminer à quelle variable une référence devrait être liée. N'utilisez pas le retour par référence pour améliorer les performances, le moteur est suffisamment robuste pour optimiser cela en interne. Retournez des références uniquement lorsque vous avez de bonnes raisons techniques de le faire ! Pour retourner des références, utilisez cette syntaxe : value; } } $obj = new foo; $myValue = &$obj->getValue(); // $myValue est une référence de $obj->value, qui vaut 42. $obj->value = 2; echo $myValue; // affiche la nouvelle valeur de $obj->value, i.e. 2. ?> ]]> Dans cet exemple, on affecte une valeur à la propriété de l'objet retourné par la fonction getValue, et non à sa copie, comme ce serait le cas si nous n'avions pas utilisé la syntaxe de référence. Contrairement au passage de paramètre, ici, vous devez utiliser & aux deux endroits, à la fois pour indiquer que vous retournez par référence (pas par copie), et pour indiquer que vous assignez aussi par référence (pas par copie non plus) pour la variable $myValue. Si vous tentez de retourner une référence depuis une fonction avec la syntaxe : return ($this->value);, cela ne fonctionnera pas comme vous l'attendez, et retournera le résultat de l'expression, et pas de la variable, par référence. Vous ne pouvez retourner que des variables par référence depuis une fonction - et rien d'autre. Pour utiliser la référence retournée, vous devez utiliser l'affectation par référence : ]]> Pour passer la référence retournée à une autre fonction attendant une référence, vous pouvez utiliser la syntaxe suivante : ]]> Notez que array_push(&collector(), 'foo'); ne fonctionnera pas, et résultera en une erreur fatale. Détruire une référence Lorsque vous détruisez une référence, vous ne faites que casser le lien entre le nom de la variable et son contenu. Cela ne signifie pas que le contenu de la variable est détruit. Par exemple : ]]> Cet exemple ne détruira pas $b, mais juste $a. Encore une fois, on peut comparer cette action avec l'appel unlink d'Unix. Repérer une référence De nombreuses syntaxes de PHP sont implémentées via le mécanisme de référence, et tout ce qui a été vu concernant les liaisons entre variables s'applique à ces syntaxes. Certaines constructions, comme le passage d'arguments et le retour par référence, ont été mentionnées plus haut. D'autres constructions qui utilisent les références sont les suivantes : Références globales Lorsque vous déclarez une variable en tant que global $var, vous créez en fait une référence sur une variable globale. Autrement dit, cela revient au même que : ]]> Cela signifie aussi que détruire la variable $var n'entrainera pas la destruction de la variable globale.