2016-10-26 1 views
23

j'ai lu beaucoup d'articles sur la façon de construire les variables à l'intérieur de la machine Zend et a trouvé une chose intéressante que je ne peux pas expliquer:La variable fait référence à lui-même

$int = 100; 
xdebug_debug_zval('int'); /// int:(refcount=1,is_ref=0),int 100 
$int = &$int; 
xdebug_debug_zval('int'); /// int:(refcount=1,is_ref=1),int 100 

Comme il se avère que nous créons le lien lui-même à lui-même? Comment est-ce possible?

information claire de ce que je sais:

En règle générale is_ref = 1 que lorsque le conteneur se réfère zval deux ou plusieurs variables de lien dur. - le nombre de variables se réfère au même conteneur zval, mais la différence est que le compteur pour différents travaux avec is_ref = 0 et is_ref = 1. Lors de la création de liens durs, nous obtenons un nouveau conteneur zval, si nous faisons l'affectation par une valeur - un nouveau conteneur zval ne sera pas créé.

Si is_ref = 1, et refcount > 1 lors de la création de liens physiques, zval n'est pas créé, utilisé ancien. si nous ne créons pas un lien dur, mais que nous assignons une valeur - cela signifie ce que nous avons créé nouveau conteneur zval.

PS J'ai écrit ceci afin de montrer que comprendre que je demande dans les commentaires et montrer pourquoi je ne comprends pas le comportement du code que je l'ai écrit ci-dessus

+0

@RyanVincent Est-ce possible? Comment est-ce que je peux faire un lien dur à la même variable, c'est à dire lui-même – MaximPro

+0

@RyanVincent Je ne te comprends pas. Je sais ce qu'une variable possède un conteneur zval – MaximPro

+0

peut-être intéressant? [Les références PHP5 expliquées visuellement] (http://www.phpinsider.com/download/PHP5RefsExplained.pdf). Plus tard et plus facile à comprendre. –

Répondre

10

La réponse est assez simple, comme expliqué à ta question. Cependant, je pense que je comprends d'où vient votre confusion, alors décomposons ça. : D

D'abord, vous affectez une valeur à une variable, en interne PHP stocke cela dans un segment de mémoire et augmente le compteur de variables qui se réfère à cette adresse. (Ref nombre = 1). Tout droit jusqu'à ce point.
Ensuite, vous réutilisez la variable pour stocker une référence (pointeur en C-termes) à cette adresse de mémoire. Le manuel de PHP explique cela en stockant une référence à une variable, pour rendre les choses plus faciles pour les programmeurs non-C, d'où (je pense) votre confusion vient. Il n'y a pas de référence à une variable dans les internes, juste les données auxquelles la variable est liée. Puisque vous avez réutilisé la variable pour stocker cette référence, le nombre de références n'augmente pas: Il n'y a toujours qu'une seule variable pointant vers ce segment de mémoire. Cependant, ce n'est plus une variable PHP normale, mais une référence (pointeur) aux données.

Modifier, a ajouté:
Une autre façon d'obtenir le même résultat, est en utilisant deux variables puis unset le premier. Exemple de code:

$a = 100; // refcount += 1 
xdebug_debug_zval ('a'); // refcount=1,is_ref=0 -> zval {value=100,type=int (addr=0x78765asd)} 

$b =& $a; // refcount += 1 
xdebug_debug_zval ('a') // refcount=2,is_ref=0 -> zval {value=100,type=int (addr=0x78765asd)} 
xdebug_debug_zval ('b') // refcount=2,is_ref=1 -> zval {value=100,type=int (addr=0x78765asd)} 

unset ($a); // refcount -= 1 
xdebug_debug_zval ('b') // refcount=1,is_ref=1 -> zval {value=100,type=int (addr=0x78765asd)} 

En utilisant seulement une variable fusionne les deux opérations en un seul, sans détruire les données. Ainsi: 1 variable (refcount = 1), qui est une référence (is_ref = 1) aux données elle-même. Comme nous avons essayé de vous expliquer la confusion provient du fait que la prémisse derrière la question initiale est erronée: Vous ne référencez pas une variable dans ces exemples, vous faites référence à une zone de mémoire qui contient les données initialement associées à cette variable. Donc vous en écrasez un ("original") "lien", avec un autre.La seule différence est que ce dernier est marqué comme tel, pour des raisons PHP internes. (Les références ne sont pas copiées à l'écriture, dans le cas de refactures> 1.)

+0

Si je vous comprends correctement que: Pas de concepts référencés de ce type de données en php, il n'y a qu'une variable qui stocke un pointeur vers un conteneur zval. Mais si tel est le cas, il n'y a pas de variables spéciales dans PHP et casse votre concept en smithereens – MaximPro

+0

Quel genre de variables spéciales pensez-vous? – ChristianF

+0

@MaximPro J'ai mis à jour ma réponse pour l'expliquer de façon légèrement différente et, espérons-le, plus claire pour vous. – ChristianF