2014-09-17 13 views
7

Non sono sicuro se questo è considerato un bugL'aggiunta di riferimenti in PHP ad un array crea un array di riferimenti

$array = ['numbers' => [1, 2, 3]]; 
foreach ($array as &$numbers) { 
    $numbers = [4, 5, 6]; 
} 
var_dump($array); 
modify_array($array); 
var_dump($array); 

function modify_array($array_arg) 
{ 
    $array_arg['numbers'] = [1, 2, 3]; 
} 

Stampe

array(1) { 
    ["numbers"]=> 
    &array(3) { 
    [0]=> 
    int(4) 
    [1]=> 
    int(5) 
    [2]=> 
    int(6) 
    } 
} 
array(1) { 
    ["numbers"]=> 
    &array(3) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(2) 
    [2]=> 
    int(3) 
    } 
} 

Si noti che $ array non è stata approvata con riferimento a modify_array () tuttavia l'array nidificato è stato modificato. Sembra logico, ma non è sicuro se questo è documentato!

risposta

4

Se si utilizza foreah con riferimento si impedisce a PHP di creare una copia dell'array, quindi si sta lavorando sull'array originale. Al termine del ciclo foreach dovresti usare la variabile unset() in loop, perché rimane ancora in memoria. Se non lo fai, otterrai risultati imprevedibili come questo presentato nella tua domanda. Anche in documentation si dispone di un avvertimento:

Attenzione di riferimento di un valore di $ e l'ultimo elemento dell'array rimangono anche dopo la foreach loop. Si consiglia di distruggerlo entro unset().

Here è possibile trovare esempi davvero buoni di foreach loop senza interruzioni.

Quindi, se si aggiunge unset(), tutto sembra come dovrebbe

$array = ['numbers' => [1, 2, 3]]; 
foreach ($array as &$numbers) { 
    $numbers = [4, 5, 6]; 
} 
unset($numbers); 
var_dump($array); 
modify_array($array); 
var_dump($array); 

function modify_array($array_arg) { 
    $array_arg['numbers'] = [1, 2, 3]; 
} 

Risultato:

array(1) { ["numbers"]=> array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) } } 
array(1) { ["numbers"]=> array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) } } 
+0

Voglio solo dire che se qualcuno vuole la conferma: http: //codepad.viper-7. com/hcpoWB L'unica cosa che ho aggiunto è stata la linea con il tag br. –

+2

"Se non lo fai, otterrai risultati imprevedibili" --- cosa ci dice che i risultati devono essere * imprevedibili *? L'avvertenza che hai citato non spiega il comportamento. – zerkms

+1

Sono d'accordo, i risultati sarebbero molto prevedibili secondo l'Avvertimento, ma questa è ancora una risposta utile oltre a questo. – PHPglue

0

Se si riscrive seguente codice:

foreach ($array as &$numbers) { 
    $numbers = [4, 5, 6]; 
} 

smth come questo:

$array['numbers'] = &$array['numbers']; 
    $array['numbers'] = [4,5,6]; 

sarà più facile capire un tale comportamento, e questo sembra essere un problema noto. (Vedi: http://php.net/manual/en/language.references.php#87532)