La respuesta rápida y sucia, pero por favor, tenga en cuenta que llamar a esta función con una referencia es obsoleto y puede (dependiendo de la configuración php) generar una advertencia:
array_splice($arr, 1, 0, array(&$var2));
El hows- y-por qué responder: lo que está sucediendo es bastante sutil. Cuando realiza el empalme, porque ha insertado una referencia en esa posición, $ var2 en realidad se está reasignando. Puede verificarlo con el siguiente código:
<?php
$hi = "test";
$var2 = "next";
$arr = array(&$hi);
$arr[] = &$var2; // this works
printf("=== var2 before splice:\n%s\n", var_export($var2, TRUE));
array_splice($arr, 1, 0, &$var2); // this doesn't
printf("=== var2 after splice:\n%s\n", var_export($var2, TRUE));
?>
obtendrá el siguiente resultado:
=== var2 before splice:
'next'
=== var2 after splice:
array (
0 => 'next',
)
en cuenta que antes del empalme, $ var2 era una cadena, tal como se esperaba que fuera ('siguiente'). Sin embargo, después del empalme, $ var2 ha sido reemplazado por una matriz que contiene un elemento, la cadena 'siguiente'.
Creo que lo que está causando es lo que dice la documentación: "Si reemplazo no es una matriz, se convertirá a uno (es decir, (matriz) $ parámetro)". Así que lo que está ocurriendo es la siguiente:
- Usted está pasando & $ var2 en una matriz como la sustitución .
- Internamente, php está convirtiendo & $ var2 en una matriz (& $ var2). En realidad podría estar haciendo algo que sea equivalente a $ param = array ($ param), lo que significa que & $ var2 se establecerá en array (& $ var2), y dado que es una referencia y no una copia de $ var2 como normalmente sería, esto está afectando a la variable que normalmente estaría fuera del alcance de la llamada.
- Ahora mueve este nuevo valor de $ var2 a la posición final e inserta una copia de $ var2 en la segunda posición.
No estoy seguro de toda la magia de lo que sucede internamente, pero $ var definitivamente se reasigna durante el empalme.Tenga en cuenta que si se utiliza una tercera variable, ya que no es la asignación de algo a algo que ya existe como una referencia, funciona como se esperaba:
<?php
$hi = "test";
$var2 = "next";
$var3 = "last";
$arr = array(&$hi);
$arr[] = &$var2; // this works
array_splice($arr, 1, 0, &$var3);
printf("=== arr is now\n%s\n", var_export($arr, TRUE));
?>
genera el resultado:
=== arr is now
array (
0 => 'test',
1 => 'last',
2 => 'next',
)
P.S. Creo que la razón por la que llamarlo con array (& $ var2) es porque internamente, splice no tiene que convertir & $ var2 a array (& $ var2) probablemente a través de la autoasignación, cambiando $ var2 en el proceso . Está creando explícitamente una nueva matriz de símbolos (& $ var2) que está físicamente separada en la memoria sin necesidad de autoasignación. –
P.P.S. Este tipo de efecto colateral involuntario es precisamente por el que la referencia de paso de llamada ha quedado obsoleta. ;) –
@AndyLobel debes cambiar la respuesta aceptada a esta. – Hamish