mi sono imbattuto in un comportamento di php molto strano (5.3.2 su ubuntu 10.04). un unset che dovrebbe verificarsi nell'ambito locale sta influenzando l'ambito della funzione del chiamante. il seguente frammento è una semplificazione del mio codice che mostra quello che posso solo supporre è un bug:php unset riferimento locale che interessa lo scope globale
<?php
function should_not_alter($in)
{
$in_ref =& $in['level1'];
should_only_unset_locally($in);
return $in;
}
function should_only_unset_locally($in)
{
unset($in['level1']['level2_0']);
}
$data = array('level1' => array('level2_0' => 'first value', 'level2_1' => 'second value'));
$data = should_not_alter($data); //test 1
//should_only_unset_locally($data); //test 2
print_r($data);
?>
se si esegue quanto sopra si vedrà che il valore 'first value'
è stato disinserito dalla matrice $data
nell'ambito globale . tuttavia se commentate test 1
ed eseguite test 2
ciò non accade.
posso solo presumere che php non mi piace fare riferimento a un elemento di un array. nel mio codice ho bisogno di modificare $in_ref
- da qui il motivo per la linea $in_ref =& $in['level1'];
nel codice sopra. Mi rendo conto che la rimozione di questa linea risolverebbe il problema di 'first value'
non impostato nell'ambito globale, ma questa non è un'opzione.
qualcuno può confermare se questo è il comportamento previsto di php?
ho il sospetto che sia un bug, piuttosto che una funzionalità, perché questo comportamento è incoerente con il modo in cui php gestisce gli ambiti ei riferimenti con le variabili normali (non-array). per esempio, utilizzando una stringa piuttosto che una funzione di matrice should_only_unset_locally()
ha alcun effetto sulla portata globale:
<?php
function should_not_alter($in)
{
$in_ref =& $in;
should_only_unset_locally($in);
return $in;
}
function should_only_unset_locally($in)
{
unset($in);
}
$data = 'original';
$data = should_not_alter($data); //test 1
//should_only_unset_locally($data); //test 2
print_r($data);
?>
sia test1 test2 o uscita original
come previsto. in realtà, anche se $data
è un array ma $in_ref
viene fatto riferimento all'intero array (ovvero $in_ref =& $in;
), il comportamento del buggy scompare.
aggiornamento
Vedo che lo sviluppatore è stato assegnato a chiuso. Non sembra che abbia interpretato correttamente il problema. Sono curioso di sapere se hai già scritto o pensato di scrivere una sorta di follow up? – Corbin
sì, ho visto anche quello. ho visto il tuo commento nella storia. sembra che lo sviluppatore non abbia capito cosa stavo cercando di mostrare. forse in realtà non ha eseguito il mio codice poiché dice che commentare la linea non fa differenza, e chiaramente lo fa. – mulllhausen