2010-04-15 4 views
5

Se eseguo l'iterazione di un array due volte, una volta per riferimento e quindi per valore, PHP sovrascriverà l'ultimo valore nell'array se utilizzo lo stesso nome di variabile per ciascun ciclo. Questo è illustrato meglio con un esempio:Perché PHP sovrascrive i valori quando eseguo l'iterazione attraverso questa matrice due volte (in base al valore)

$array = range(1,5); 
foreach($array as &$element) 
{ 
    $element *= 2; 
} 
print_r($array); 
foreach($array as $element) { } 
print_r($array); 

uscita:

Array ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10)

Array ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8)

Nota che non sono t cercando una soluzione, sto cercando di capire perché questo sta accadendo. Si noti inoltre che non si verifica se i nomi delle variabili in ciascun ciclo non sono tutti denominati $element, quindi suppongo che abbia a che fare con $element ancora nell'ambito e un riferimento dopo la fine del primo ciclo.

risposta

7

Dopo il primo ciclo, $ elemento è ancora un riferimento all'ultimo elemento/valore di $ array.
Si può vedere che quando si utilizza var_dump() al posto di print_r()

array(5) { 
    [0]=> 
    int(2) 
... 
    [4]=> 
    &int(2) 
} 

noti che & in &int(2).
Con il secondo ciclo si assegna valori a $ elemento. E poiché è ancora un riferimento, anche il valore nella matrice viene modificato. Provalo con

foreach($array as $element) 
{ 
    var_dump($array); 
} 

come il secondo ciclo e vedrai.
quindi è più o meno lo stesso di

$array = range(1,5); 
$element = &$array[4]; 
$element = $array[3]; 
// and $element = $array[4]; 
echo $array[4]; 

(solo con i loop e la moltiplicazione ... Ehi, ho detto "più o meno" ;-))

+0

Grazie! Questo ha perfettamente senso. –

5

Ecco an explanation from the man himself:

$y = "some test"; 

foreach ($myarray as $y) { 
    print "$y\n"; 
} 

Qui $y è una voce di tabella di simboli che fa riferimento a una stringa contenente "alcuni test". Sulla prima iterazione si fa essenzialmente:

$y = $myarray[0]; // Not necessarily 0, just the 1st element 

Così ora la memoria associata $y viene sovrascritto dal valore da $myarray. Se $y è associato a un altro archivio tramite un riferimento , tale spazio di archiviazione sarà modificato.

Ora diciamo che si esegue questa operazione:

$myarray = array("Test"); 
$a = "A string"; 
$y = &$a; 

foreach ($myarray as $y) { 
    print "$y\n"; 
} 

Qui $y è associato con lo stesso storage come $a attraverso un riferimento in modo quando la prima iterazione fa:

$y = $myarray[0]; 

L'unico posto quella stringa "Test" può go è nella memoria associata a $y.

1

Questo è come si dovrebbe risolvere questo problema:

foreach($array as &$element) 
{ 
    $element *= 2; 
} 
unset($element); #gets rid of the reference and cleans the var for re-use. 

foreach($array as $element) { } 
Problemi correlati