Descargo de responsabilidad: No he podido encontrar una referencia explícita para esto, por lo que principalmente infiero aquí.
Una referencia regular funciona a través de la tabla de símbolos. Al crear una variable y un valor, tanto se almacenan en la tabla de símbolos local de este modo:
$foo = "bar";
+--------+-------+
| symbol | value |
+--------+-------+
| $foo | "bar" |
+--------+-------+
Cuando se crea una referencia, esto simplemente añade otro símbolo para el mismo valor de la tabla:
$bar =& $foo;
+------------+-------+
| symbol | value |
+------------+-------+
| $foo, $bar | "bar" |
+------------+-------+
claves de matriz se almacenan de forma diferente sin embargo:
$var[0] = 'a';
+--------+-----------------+
| symbol | value |
+--------+-----------------+
| $var | array(0 => 'a') |
+--------+-----------------+
Hay una entrada en la tabla de símbolos para $var
, pero los valores dentro de la matriz no están referenciados individualmente en la tabla de símbolos. Lo deduzco debe estar sucediendo cuando se crea una referencia al valor 'a'
(almacenado en $var[0]
) es que el valor 'a'
se separa de la matriz $var
y $var[0]
mismo se convierte en una referencia a la nueva ubicación del lugar donde se almacena 'a'
:
$foo =& $var[0];
+--------+------------------+
| symbol | value |
+--------+------------------+
| $var | array(0 => %REF) |
| $foo | %REF |
| %REF | 'a' |
+--------+------------------+
Supongo que la implementación interna de la tabla de símbolos no permite crear referencias directas a las teclas de matriz, por lo tanto, esta es la única forma de crear una referencia a un elemento de matriz.
Así que cuando se copia $var
a $tmp
, la referencia se copia con él:
$tmp = $var;
+--------+------------------+
| symbol | value |
+--------+------------------+
| $var | array(0 => %REF) |
| $foo | %REF |
| %REF | 'a' |
| $tmp | array(0 => %REF) |
+--------+------------------+
Luego, cuando se cambia el valor $var[0]
se refiere a, cambia el valor de %REF
, que tanto $tmp
y $var
se refieren a.
Como dije, esto puede o no ser una explicación precisa de lo que sucede internamente, pero ilustra el principio.
Tenga en cuenta que los diversos términos "pass-by- *" solo se aplican a los argumentos de la función.No hay ninguna variable que pase aquí, solo asignación. – outis