2012-02-24 8 views
6

Kiedy biegnę cios kodu:Dlaczego zmienna przypisana wartości do elementu tablicy (po wcześniejszym przypisaniu przez odniesienie) zmienia się po zmianie elementu tablicy?

$var[0] = 'a'; 
$tmp = $var; 
$var[0] = 'b'; 
var_dump($tmp); 

wyjście jest:

array(1) { [0]=> string(1) "a" } 

Kiedy dodać linię następująco:

$var[0] = 'a'; 
$foo = & $var[0]; # added line 
$tmp = $var; 
$var[0] = 'b'; 
var_dump($tmp); 

wyjście uruchamia się:

array(1) { [0]=> &string(1) "b" } 

Jeśli przypiszę zmienną $foo przez odniesienie do elementu tablicy $var[0], czy zmienna $tmp przypisana przez wartość do tablicy $var ma się tak zmienić? Dlaczego to się dzieje?

+0

Należy zauważyć, że różne terminy "pass-by- *" mają zastosowanie tylko do argumentów funkcji.Nie ma tutaj żadnej zmiennej, tylko przypisanie. – outis

Odpowiedz

3

Nota prawna: Nie byłem w stanie znaleźć wyraźnego odniesienia do tego, więc w zasadzie się tutaj domyślam.

Regularne odniesienie działa poprzez tabelę symboli. Podczas tworzenia zmiennej i wartość, oba są przechowywane w lokalnej tablicy symboli tak:

$foo = "bar"; 

+--------+-------+ 
| symbol | value | 
+--------+-------+ 
| $foo | "bar" | 
+--------+-------+ 

gdy odwołanie jest tworzony, to po prostu dodaje inny symbol dla tej samej wartości do tabeli:

$bar =& $foo; 

+------------+-------+ 
| symbol  | value | 
+------------+-------+ 
| $foo, $bar | "bar" | 
+------------+-------+ 

kluczy tablicy są zapisywane w różny sposób jednak:

$var[0] = 'a'; 

+--------+-----------------+ 
| symbol | value   | 
+--------+-----------------+ 
| $var | array(0 => 'a') | 
+--------+-----------------+ 

jest wpis w tablicy symboli dla $var, ale wartości wewnątrz tablicy nie są indywidualnie mowa w tabela symboli. Co wywnioskować, musi się zdarzyć podczas tworzenia odniesienia do wartości 'a' (przechowywanym w $var[0]) jest to, że wartość 'a' jest oddzielona od układu $var i sam $var[0] się odniesienie do nowego położenia, w którym są przechowywane 'a':

$foo =& $var[0]; 

+--------+------------------+ 
| symbol | value   | 
+--------+------------------+ 
| $var | array(0 => %REF) | 
| $foo | %REF    | 
| %REF | 'a'    | 
+--------+------------------+ 

Domyślam się, że wewnętrzna implementacja tabeli symboli nie pozwala na tworzenie bezpośrednich odwołań do kluczy tablic, dlatego jest to jedyny sposób utworzenia odwołania do elementu tablicy.

Więc podczas kopiowania $var do $tmp odniesienie jest kopiowany z nim:

$tmp = $var; 

+--------+------------------+ 
| symbol | value   | 
+--------+------------------+ 
| $var | array(0 => %REF) | 
| $foo | %REF    | 
| %REF | 'a'    | 
| $tmp | array(0 => %REF) | 
+--------+------------------+ 

Potem, gdy zmiana wartości $var[0] odnosi się to zmienia wartość %REF, które odnoszą się zarówno do $tmp i $var.

Jak już powiedziałem, może to być dokładne wyjaśnienie tego, co dzieje się wewnątrz, ale to ilustruje zasadę.

Powiązane problemy