Question

Je reçois des signaux mitigés partout.

Dois-je utiliser l'ampesand pour passer des variables par référence ou non?

Le lien suivant semble me dire qu'il est obsolète et plus nécessaire:
http://gtk.php.net/manual/en/html/tutorials/tutorials.changes.references.html

Mais des fils comme ceux-ci me font me demander:
Pass-by-by-by-référence Dégrâce?
PHP et Ampersand

Permettez-moi de phraser ma question à titre d'exemple.

Si je fais une fonction, en utilisant PHP 5.5.5:

function recurring_mailer_form($form, $form_state) 
{

}

Est-ce la même chose que:

function recurring_mailer_form($form, &$form_state) 
{

}

?

Était-ce utile?

La solution

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.

Autres conseils

Non, ce n'est pas le cas.

  • Les objets sont toujours transmis automatiquement sous forme de références (Info! Voir ci-dessous pour des informations importantes supplémentaires!)

  • Déclarer les paramètres en tant que références doit se produire à la définition de la fonction:

    function test(&$var) {}
    

    Pas Au moment de l'appeler:

    // wrong
    $var = '123';
    test(&$var);
    


Si vous passez un objet comme d'habitude, vous pouvez modifier l'état de l'objet (propriétés).
Suppose que $obj est une instance de la classe TestClass qui contient une variable de membre appelée hello (Cliquez ici pour un échantillon complet sur iDeOne.com):

function modify($obj) { $obj->hello = 'world (modified)!'; }

$obj->hello = 'world';
modify($obj);
var_dump($obj->hello);  // outputs "world (modified!)"

Cela devrait être explicite. Maintenant, en utilisant le même code mais en attribuant une autre valeur à $obj Au lieu de cela, la modification de l'état de l'objet entraîne aucune modification (→ ideone.com):

function modify($obj) { $obj = 42; }
// ...
var_dump($obj->hello);  // outputs "world"

Accepter uniquement le paramètre explicitement en tant que référence nous donne la possibilité de modifier complètement le contenu de la variable (→ ideone.com):

function modify(&$obj) { $obj = 42; }
// ...
var_dump($obj);         // outputs "42"

Non, ce ne sont pas les mêmes. PHP 5.4+ détecte simplement sur l'appel si une référence est nécessaire lorsque la fonction est appelée en vérifiant la déclaration.

Donc non, non déprécié car vous avez besoin de l'opérateur de référence dans la déclaration de fonction si c'est votre utilisation prévue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top