Bug PHP con conversione di oggetto in array
Domanda
Ho avuto questa domanda in precedenza ed è stato concluso che era un bug in 5.2.5. Bene, è ancora rotto in 5.2.6, almeno per me:
Per favore fatemi sapere se è rotto o funziona per voi:
$obj = new stdClass();
$obj->{"foo"} = "bar";
$obj->{"0"} = "zero";
$arr = (array)$obj;
//foo -- bar
//0 -- {error: undefined index}
foreach ($arr as $key=>$value){
echo "$key -- " . $arr[$key] . "\n";
}
Qualsiasi modo per " correggere " l'array dopo che è stato trasmesso da una stdClass?
Soluzione
Sicuramente mi sembra un bug (PHP 5.2.6).
È possibile correggere l'array in questo modo:
$arr = array_combine(array_keys($arr), array_values($arr));
È stato segnalato in questa segnalazione di bug ma contrassegnato come falso .. . dice la documentazione :
Le chiavi sono la variabile membro nomi, con alcune notevoli eccezioni: le proprietà intere sono inaccessibili;
Altri suggerimenti
Un po 'di sperimentazione mostra che le proprie funzioni di phps non persistono questa debolezza.
function noopa( $a ){ return $a; }
$arr = array_map('noopa', $arr );
$arr[0]; # no error!
Questo in effetti, crea una copia dell'array e la correzione si verifica durante la copia.
In definitiva, si tratta di un errore di progettazione su tutta la linea, provare a utilizzare array_merge nel modo in cui pensi che funzioni su un array con tasti numerici e stringa combinati?
Tutti gli elementi numerati vengono copiati e alcuni vengono riclassificati, anche se alcuni sono semplicemente numeri incapsulati in stringa e, di conseguenza, esistono decine di implementazioni homebrew di array_merge solo per risolvere questo problema.
Ai tempi in cui php cercava di creare un clone di perl e falliva, non afferrarono il concetto di array e hash come concetti distinti, anzi li misero insieme in un unico ombrello universale. Ben fatto!.
Per il loro prossimo trucco, riescono a rompere i delimitatori dello spazio dei nomi a causa di alcuni problemi tecnici che nessun altro linguaggio ha incontrato per qualche motivo.
Grazie RoBorg .. L'ho appena scoperto anche io :)
Ecco un'altra soluzione, non sono sicuro che sia più veloce o meno:
unserialize(serialize($arr));