multidimensional - recorrer array asociativo php
La matriz de PHP con claves numéricas como cadena no se puede usar (6)
Esta pregunta ya tiene una respuesta aquí:
Tengo una matriz de PHP que tiene claves numéricas como un tipo de cadena.
Pero cuando intento acceder a ellos, PHP me está dando un error de índice no definido.
$a = (array)json_decode(''{"1":1,"2":2}'');
var_dump($a);
var_dump(isset($a[1]));
var_dump(isset($a["1"]));
var_dump($a[1]);
var_dump($a["1"]);
Salida:
array (size=2) ''1'' => int 1 ''2'' => int 2 boolean false boolean false ERROR: E_NOTICE: Undefined offset: 1 null ERROR: E_NOTICE: Undefined offset: 1 null
¿Cómo accedo a estos valores?
Demostración: http://codepad.viper-7.com/8O03IM
Aparentemente, este es un problema conocido, y no hay planes para solucionarlo; ver Doc Bug # 45959 La conversión de objetos a matrices conduce a un comportamiento extraño :
Arreglo que implica una disminución del rendimiento, por lo tanto, mejor parece ser mantenerlo como un problema conocido, pero documentado.
Esta información es (entonces) anotada en la documentación para el tipo de matriz (el énfasis es mío):
Si un objeto se convierte en una matriz, el resultado es una matriz cuyos elementos son las propiedades del objeto. Las claves son los nombres de las variables miembro, con algunas excepciones notables: las propiedades de enteros no son accesibles ... Esto puede dar como resultado un comportamiento inesperado ...
Entonces, no he visto ninguna otra respuesta que toque esto, pero @xdazz estuvo cerca.
Comencemos nuestro entorno, $obj
es igual a la notación de objeto de una cadena decodificada:
php > $obj = json_decode(''{"1":1,"2":2}'');
php > print_r($obj);
stdClass Object
(
[1] => 1
[2] => 2
)
php > var_dump( $obj );
object(stdClass)#1 (2) {
["1"]=>
int(1)
["2"]=>
int(2)
}
Si desea acceder a las cadenas, sabemos que fallará lo siguiente:
php > echo $obj->1;
Parse error: parse error, expecting `T_STRING'' or `T_VARIABLE'' or `''{'''' or `''$'''' in php shell code on line 1
Accediendo a las variables de objeto.
Se puede acceder así:
php > echo $obj->{1};
1
Lo que es lo mismo que decir:
php > echo $obj->{''1''};
1
Accediendo a las variables del array.
El problema con las matrices es que lo siguiente aparece en blanco, que es el problema con el encasillado.
php > echo $obj[1];
php >
Si lo escribes de nuevo, el objeto es nuevamente accesible:
php > $obj = (object) $obj;
php > echo $obj->{1};
1
Aquí hay una función que automatizará lo anterior para usted:
function array_key($array, $key){
$obj = (object) $array;
return $obj->{$key};
}
Ejemplo de uso:
php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1
php > echo array_key($obj, 2);
2
Me encontré con el mismo problema recientemente.
$obj = new stdClass();
$obj->{''0''} = "test";
$array = (array)$obj;
foreach ($array as $key => $value) {
$array[$key] = strtoupper($value);
}
var_dump($array);
Este código produce:
array(2) {
["0"]=>
string(4) "test"
[0]=>
string(4) "TEST"
}
Descubrí que al depurar un método para convertir objetos recursivos en una matriz, he estado enojado.
Sí. Estoy de acuerdo, PHP tiene problemas con el encasillado de un objeto a otro, pero foreach está manejando de manera inteligente el objeto o el conjunto asociativo.
$a = json_decode(''{"1":1,"2":2}''); //need not typecast but doesnt break even if u typecast
foreach ($a as $k=>$v){
echo $v;
}
Si desea una matriz, establezca el segundo parámetro de json_decode en true
.
$a = json_decode(''{"1":1,"2":2}'', true);
Edición: cuando se convierte un objeto estándar en una matriz, la clave numérica de cadena no se convierte en número. Aquí hay un ejemplo.
$obj = new stdClass;
$obj->{''1''} = 1;
$arr = (array) $obj;
var_dump($arr);
var_dump(isset($arr[1]));
Tuve el mismo problema (pero con array_intersect_key).
Aquí está mi solución:
$array = array_combine(array_keys($array), $array);