La risposta rapida e-sporca, ma si prega di essere consapevole del fatto che chiamare questa funzione con un riferimento è deprecato e può (a seconda della configurazione di PHP) generano un avvertimento:
array_splice($arr, 1, 0, array(&$var2));
Il hows- e-perché risponde: quello che sta succedendo è piuttosto sottile. Quando esegui la giunzione, poiché hai inserito un riferimento in quella posizione, $ var2 viene effettivamente riassegnato. È possibile verificare con il seguente codice:
<?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));
?>
si otterrà il seguente risultato:
=== var2 before splice:
'next'
=== var2 after splice:
array (
0 => 'next',
)
noti che prima della giunzione, $ var2 era una stringa, proprio come vi aspettavate di essere ('Il prossimo'). Dopo la giunzione, tuttavia, $ var2 è stata sostituita con un array contenente un elemento, la stringa 'next'.
Credo che ciò che è la causa è ciò che la documentazione dice: "Se la sostituzione non è un array, verrà typecast a uno (vale a dire (array) $ parametro)" Quindi, ciò che sta accadendo è questo:
- si sta passando & $ var2 in array come sostituzione.
- Internamente, php sta convertendo & $ var2 in array (& $ var2). Potrebbe effettivamente fare qualcosa che è equivalente a $ param = array ($ param), il che significa che & $ var2 sarà impostato su array (& $ var2), e poiché è un riferimento e non una copia di $ var2 come normalmente sarebbe, questo sta influenzando la variabile che normalmente sarebbe al di fuori della portata della chiamata.
- Ora sposta questo nuovo valore di $ var2 nella posizione finale e inserisce una copia di $ var2 nella seconda posizione.
Non sono sicuro di conoscere esattamente la magia di ciò che accade internamente, ma $ var viene definitivamente riassegnato durante la giunzione.Si noti che se si utilizza una terza variabile, poiché non è l'assegnazione di qualcosa a qualcosa che già esiste come riferimento, funziona come previsto:
<?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 il risultato:
=== arr is now
array (
0 => 'test',
1 => 'last',
2 => 'next',
)
P.S. Penso che la ragione per cui la chiamata con array (& $ var2) funzioni è perché internamente, splice non deve convertire & $ var2 in array (& $ var2) probabilmente attraverso l'autoassegnazione, cambiando così $ var2 nel processo . Stai creando in modo esplicito un nuovo array di simboli (& $ var2) fisicamente separato in memoria senza bisogno di autoassegnazione. –
P.P.S. Questo tipo di effetto collaterale non intenzionale è precisamente il motivo per cui il pass-by-reference del tempo di chiamata è stato deprecato. ;) –
@AndyLobel dovresti cambiare la risposta accettata a questa. – Hamish