La raison pour laquelle différents articles semblent dire différentes choses est qu'ils parlent de différents types de référence.
La principale chose qui détermine si un paramètre doit être transmis par référence est la signature de fonction elle-même, et les principes fondamentaux de cela n'ont pas changé depuis PHP 4. Considérez cet exemple:
function foo( $by_value, &$by_reference ) { /* ... */ }
$a = 1; $b = 2;
foo( $a, $b );
Ici, la variable extérieure $a
est transmis à la fonction par valeur, comme s'il était attribué comme $by_value = $a;
- Modifications à $by_value
ne peut pas affecter $a
. La variable $b
Cependant, il est passé par référence; Tout comme une affectation du formulaire $by_reference =& $b;
Cela signifie qu'il existe une variable référencée par deux noms, et toute affectation à une agira comme une affectation aux deux.
Si vous passez une valeur "ordinaire" (une chaîne, un nombre ou un tableau) par valeur, sa valeur est juste copiée dans la nouvelle variable. Depuis PHP 5: Si vous passez un objet par valeur, cependant, quelque chose de légèrement différent se produit - la "valeur" copiée n'est qu'un pointeur vers le même objet. Cela signifie que si $a
étaient un objet, tu pouvais appeler $by_value->some_property = 42;
et $a->some_property
serait aussi 42
. Cependant, si vous avez attribué une nouvelle valeur à $by_value
, cela n'affecterait toujours pas $a
.
Jusqu'à PHP 5.4, il y avait un En plus moyen de passer un paramètre par référence, qui devait "forcer" le comportement de référence au moment de l'appel. Cela signifiait que tu pouvais écrire foo(&$a, &$b);
et "capturer" modifications apportées à $by_value
à l'intérieur de foo()
fonction. S'appuyer sur cela était généralement une mauvaise idée, et il a donc été supprimé. (Il a atterri en 5,4 parce qu'il était destiné à l'élimination dans PHP 6, mais ce projet a été mis en attente indéfinie, les changements plus petits atterrissant en 5,3 et 5,4).
Enfin, les fonctions peuvent revenir une variable par référence (comme discuté dans le manuel ici). C'est un peu délicat, car cela vous oblige réellement à mettre &
dans deux lieux: au début de la déclaration de fonction, pour dire que return
devrait signifier "renvoyer cette référence de variable" non "renvoie cette valeur"; et dans le code l'appelant, pour attribuer une variable à cette référence, plutôt que de simplement copier sa valeur. Voici un exemple idiot qui combine un paramètre de référence avec un retour de référence (les deux n'ont pas à aller ensemble, c'est juste un exemple):
function &bar(&$some_param) { return $some_param; }
$a = 1;
$b =& bar($a);
// $b and $a now point at the same variable, not just the same value
// it was passed into and out of a function, and assigned to a new variable,
// but all those operations were by reference
Notez que de nombreuses personnes croient à tort que le passage d'une variable par référence leur donnera un avantage de performance, et c'était souvent leur seule raison d'utiliser la référence du temps d'appel. C'est en fait généralement faux, car le moteur Zend qui alimente PHP utilise une technique appelée "Copier On Write" pour laisser plusieurs variables qui ont la même valeur pointant sur le même morceau de mémoire, même s'ils ne sont pas liés comme références. En fait, l'attribution de référence généralement défaites Cette optimisation, en raison de la façon dont le moteur suit les variables dans l'état de copie-écriture.