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ę.
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