2015-11-13 11 views
15

Ho riscontrato qualcosa di strano.Elemento array di accesso indicizzato da stringa numerica

Ho una matrice php, indicizzata con tasti numerici. Tuttavia sembra impossibile accedere ad uno qualsiasi degli elementi perché php tratta automaticamente le stringhe numeriche come numeri interi, causando un avviso di offset illegale.

In circostanze normali è imposabile creare un array php con indici stringa numerici, ma può succedere con il casting di tipo.

di riprodursi:

$object = new stdClass(); 
$object->{'1'} = 'one'; 

$array = (array) $object; 

var_dump($array); 
/* produces 
array(1) { 
    ["1"]=> 
    string(3) "one" 
} 
*/ 

//none of the following will work 
$key = '1'; 
echo $array[1], $array['1'], $array["1"], $array[(string)1], $array[$key]; 

Si tratta solo di un caso bug bordo? Ho incontrato solo il problema quando si tenta di migliorare la mia risposta per another SO question

esempio di codice in diretta: http://codepad.viper-7.com/dFSlH1

+0

Penso che stia accadendo quando converti da un oggetto all'altro. Perché funziona bene se si tratta di un array associativo. Esempio: http://codepad.viper-7.com/wskYI9 –

+0

Inoltre, se si utilizza l'approccio 'json_decode (json_encode ($ object), true)' piuttosto disordinato, questo problema non si verifica – Dale

+2

Alcune informazioni qui http: //php.net/manual/en/language.types.array.php#language.types.array.casting – danjam

risposta

11

Incredibile ma questo è un comportamento normale in PHP, è stato considerato come un bug (link) nell'anno 2008.

Ma hanno solo sottolineato la manual per il cast con (array):

Se un oggetto viene convertito in un array, il risultato è un array i cui elementi sono le proprietà dell'oggetto. Le chiavi sono i nomi delle variabili membro , con alcune eccezioni degne di nota: Le proprietà integer sono inaccessibile;

È possibile utilizzare get_object_vars() invece:

$object = new stdClass(); 
$object->{'1'} = 'one'; 

$array = get_object_vars($object); 

$key = '1'; 
echo $array[1]."<br>"; 
echo $array['1']."<br>"; 
echo $array["1"]."<br>"; 
echo $array[(string)1]."<br>"; 
echo $array[$key]."<br>"; 

non spiega il motivo per cui questo accade, ma è una soluzione per evitare il problema cast.

Off topic ma ho pensato che forse è interessante. Trovato nel manual.

Per evitare questo tipo di problemi, utilizzare sempre un intero O una stringa come indice, non confonderlo e non utilizzare numeri interi in una stringa.

Esempio di matrice mista:

$array = array(
    1 => "a", 
    "1" => "b",//overrides 1 
    1.5 => "c",//overrides "1" 
    true => "d",//overrides 1.5 
); 

var_dump($array); 
5

È possibile utilizzare

$vars = get_object_vars($object); 
echo $vars[1]; 
+1

oh fantastico, eri più veloce di me :) – swidmann

2

chiavi string contenenti valori interi validi sarebbero espressi per chiavi intere automaticamente nella creazione matrice “normale” - ma sembra colata dall'oggetto matrice non si applica la stessa logica.

Può essere fissato tuttavia, utilizzando

$array = array_combine(array_keys($array), array_values($array)); 

dopo la linea che crea la matrice dall'oggetto.http://codepad.viper-7.com/v5rGJa


Anche se, proprio come Dave già detto nel suo commento, utilizzando get_object_vars sembra una soluzione più “pulito” per me.

1
foreach ($array as $key => $value){ 
    var_dump($key); 
    var_dump($value); 
} 

mostra

string(1) "1" 
string(3) "one" 

Ma echo $array['"1"'];

E_NOTICE : type 8 -- Undefined index: "1" -- at line 8 

Che strano!

Problemi correlati