2017-09-28 1 views

Répondre

3

En termes simples, les références sont des alias.

Une variable en PHP est stockée en deux parties: le nom et la valeur. Le nom pointe vers la valeur.

$x = 2; 
$y = $x; 
$z = &$x; 

Lorsque $x = 2; est exécuté, le nom x est stocké dans la table des symboles de la portée actuelle et la valeur 2 est stockée dans un zval (ne demandez pas, c'est le nom interne d'une structure de données qui stocke une valeur en PHP).

Lorsque $y = $x; est exécuté, le nom y est stocké dans la table des symboles de la portée actuelle et la valeur de $x (2) est copiée dans une nouvelle structure zval.

Lorsque $z = &$x; est exécuté, le nom z est stocké dans la table de symboles de la portée actuelle, mais un nouveau zval n'est pas créé. Au lieu de cela, z est défini pour pointer sur le même zval que x.

La mémoire utilisée par les variables $x, $y et $z ressemble à ceci:

+---------+    +---------+ 
| x | -------------> | 2 | 
+---------+    +---------+ 
           ^
+---------+      |  +---------+ 
| y | -------------------------> | 2 | 
+---------+      |  +---------+ 
           | 
+---------+      | 
| z | --------------------+ 
+---------+ 

Lorsqu'une valeur est passée par référence à une fonction ou une fonction renvoie une référence les mêmes choses se passent, seuls les noms sont stockés dans différentes tables de symboles (remarquez le "current scope" dans l'explication ci-dessus).

Voyons ce code:

function f(& $z) { 
    $y = $z; 
    $z = $z + 2; 
} 
$x = 2; 
f($x); 

Après $x = 2; la mémoire ressemble à ceci:

+---------+    +---------+ 
| x | -------------> | 2 | 
+---------+    +---------+ 

Au cours de l'exécution de la fonction f(), la mémoire ressemble à ceci:

+===== global ====+ 
| +---------+ |   +---------+ 
| | x | -------------> | 4 | 
| +---------+ |   +---------+ 
+=================+    ^
            | 
+====== f() ======+     | 
| +---------+ |     |  +---------+ 
| | y | -------------------------> | 2 | 
| +---------+ |     |  +---------+ 
|     |     | 
| +---------+ |     | 
| | z | --------------------+ 
| +---------+ | 
+=================+ 

y et z sont s Ils sont supprimés (avec la totalité de la table de symboles qui les contient) lorsque l'appel à f() est renvoyé dans une table de symboles différente de x.

Lorsque y est supprimé, sa valeur est également supprimée car aucun nom ne pointe plus vers cette valeur. Mais, parce que la valeur pointée par z est également pointée par x ($z est un alias), la valeur n'est pas supprimée avec z et il survit à l'appel de la fonction. f() modifie la valeur à l'aide de $z; et ce changement est visible dans le programme principal à travers la variable $x.

Les choses se passent de la même manière lorsqu'une fonction renvoie une référence. La fonction renvoie une valeur qui n'est pas copiée mais un nouveau nom qui pointe vers elle est créé dans la table de symboles du code appelant.

+0

Alors, quelle est l'histoire de référencer le ** passage par référence ** dans la fonction ?? –

+0

plus sur [zval] (http://www.phpinternalsbook.com/php7/internal_types/zvals.html) – hassan

0

Je vous suggère d'étudier les pointeurs en langage C si vous avez des doutes sur ce qu'ils sont.

Quoi qu'il en soit, cela est une explication très simplifiée:

références ne sont pas la mémoire traite que les variables de points, mais ils sont seulement un moyen de passer un paramètre à une fonction et retourner ce paramètre modifié si la fonction le modifier .