Estoy usando json_decode()
algo como:
$myVar = json_decode($data)
Lo que me da un resultado como este:
[highlighting] => stdClass Object
(
[448364] => stdClass Object
(
[Data] => Array
(
[0] => Tax amount liability is .......
Quiero acceder al valor de la cadena en la clave [0]. Cuando intento hacer algo como:
print $myVar->highlighting->448364->Data->0;
Me sale este error:
Error de análisis: error de sintaxis, T_DNUMBER inesperado
Los dos números / enteros parece haber un problema.
php
object
properties
avinash shah
fuente
fuente
Respuestas:
Actualizado para PHP 7.2
PHP 7.2 introdujo un cambio de comportamiento en la conversión de claves numéricas en conversiones de objetos y matrices , que corrige esta inconsistencia particular y hace que todos los siguientes ejemplos se comporten como se esperaba.
¡Una cosa menos por la que estar confundido!
Respuesta original (se aplica a versiones anteriores a la 7.2.0)
PHP tiene su parte de callejones oscuros en los que realmente no quieres encontrarte dentro. Las propiedades de objetos con nombres que son números es una de ellas ...
Lo que nunca te dijeron
Hecho # 1: No puede acceder fácilmente a propiedades con nombres que no son nombres de variables legales
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->123foo; // error
Hecho # 2: Usted puede acceder a estas propiedades con la sintaxis de corchete
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->{'123foo'}; // OK!
Hecho # 3: ¡ Pero no si el nombre de la propiedad es todo dígitos!
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; echo $o->{'123foo'}; // OK! echo $o->{'123'}; // error!
Ejemplo vivo .
Hecho # 4: Bueno, a menos que el objeto no provenga de una matriz en primer lugar.
$a = array('123' => '123'); $o1 = (object)$a; $o2 = new stdClass; $o2->{'123'} = '123'; // setting property is OK echo $o1->{'123'}; // error! echo $o2->{'123'}; // works... WTF?
Ejemplo vivo .
Bastante intuitivo, ¿no estás de acuerdo?
Lo que puedes hacer
Opción # 1: hazlo manualmente
El enfoque más práctico es simplemente convertir el objeto que le interesa de nuevo en una matriz, lo que le permitirá acceder a las propiedades:
$a = array('123' => '123', '123foo' => '123foo'); $o = (object)$a; $a = (array)$o; echo $o->{'123'}; // error! echo $a['123']; // OK!
Desafortunadamente, esto no funciona de forma recursiva. Entonces, en su caso, necesitaría hacer algo como:
$highlighting = (array)$myVar->highlighting; $data = (array)$highlighting['448364']->Data; $value = $data['0']; // at last!
Opción # 2: la opción nuclear
Un enfoque alternativo sería escribir una función que convierta objetos en matrices de forma recursiva:
function recursive_cast_to_array($o) { $a = (array)$o; foreach ($a as &$value) { if (is_object($value)) { $value = recursive_cast_to_array($value); } } return $a; } $arr = recursive_cast_to_array($myVar); $value = $arr['highlighting']['448364']['Data']['0'];
Sin embargo, no estoy convencido de que esta sea una mejor opción en todos los ámbitos porque, innecesariamente, enviará a matrices todas las propiedades que no le interesan y las que le interesan.
Opción n. ° 3: jugar de manera inteligente
Una alternativa a la opción anterior es utilizar las funciones JSON integradas:
$arr = json_decode(json_encode($myVar), true); $value = $arr['highlighting']['448364']['Data']['0'];
Las funciones JSON realizan de manera útil una conversión recursiva a una matriz sin la necesidad de definir funciones externas. Por muy deseable que parezca, tiene la desventaja "nuclear" de la opción # 2 y además la desventaja de que si hay cadenas dentro de su objeto, esas cadenas deben estar codificadas en UTF-8 (este es un requisito de
json_encode
).fuente
->date
o->timezone
, solonull
se devuelve. Me di cuenta de que si var_dumped el objeto antes de usar estas propiedades, se devuelven los valores adecuados. La clonación no soluciona esto, así que supongo que realmente tiene algo que ver con el acceso quevar_dump
sí ... Entonces vi tu Opción # 1 y voilá, acceder a ella como una matriz ($objCastAsArray['date']
) funcionó como un encanto.$o = unserialize('O:8:"StdClass"' . substr(serialize($a),1));
Solo quería agregar a la elocuente explicación de Jon la razón por la que esto falla. Todo se debe a que al crear una matriz, php convierte claves en números enteros, si puede, lo que causa problemas de búsqueda en matrices que se han convertido en objetos, simplemente porque se conserva la clave numérica. Esto es problemático porque todas las opciones de acceso a la propiedad esperan o se convierten en cadenas. Puede confirmar esto haciendo lo siguiente:
$arr = array('123' => 'abc'); $obj = (object) $arr; $obj->{'123'} = 'abc'; print_r( $obj );
Que daría como resultado:
stdClass Object ( [123] => 'abc', [123] => 'abc' )
Entonces, el objeto tiene dos claves de propiedad, una numérica (a la que no se puede acceder) y una basada en cadena. Esta es la razón por la que Jon's
#Fact 4
funciona, porque al establecer la propiedad con llaves significa que siempre define una clave basada en cadenas, en lugar de numérica.Tomando la solución de Jon, pero dándole la vuelta, puede generar un objeto de su matriz que siempre tiene claves basadas en cadenas haciendo lo siguiente:
De ahora en adelante, puede usar cualquiera de los siguientes, porque el acceso de esta manera siempre convierte el valor dentro de la llave en una cadena:
$obj->{123}; $obj->{'123'};
El buen PHP ilógico ...
fuente
Si un objeto comienza con
@
like:SimpleXMLElement Object ( [@attributes] => Array ( [href] => qwertyuiop.html [id] => html21 [media-type] => application/xhtml+xml ) )
Tienes que usar:
porque
$parent_object->{'@attributes'}
o$parent_object['@attributes']
no funcionará.fuente
Había copiado esta función de la red. Si funciona como dice ("Función para convertir objetos stdClass en matrices multidimensionales"), intente lo siguiente:
<?php function objectToArray($d) { if (is_object($d)) { // Gets the properties of the given object // with get_object_vars function $d = get_object_vars($d); } if (is_array($d)) { /* * Return array converted to object * Using __FUNCTION__ (Magic constant) * for recursive call */ return array_map(__FUNCTION__, $d); } else { // Return array return $d; } } ?>
objectToArray
función[highlighting][448364][Data][0]
Fuente: PHP stdClass a Array y Array a stdClass
fuente
Una alternativa final a la respuesta integral de Jon:
Simplemente use json_decode () con el segundo parámetro establecido en verdadero .
$array = json_decode($url, true);
Esto luego devuelve una matriz asociativa en lugar de un objeto, por lo que no es necesario convertir después del hecho.
Puede que esto no sea adecuado para todas las aplicaciones, pero realmente me ayudó a hacer referencia fácilmente a una propiedad del objeto original.
Se encontró una solución en este tutorial: http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
Saludos
fuente
Acceso a las propiedades del objeto que tienen números como nombre de propiedad. Se necesita principalmente después de lanzar una matriz a un objeto.
$arr = [2,3,7]; $o = (object) $arr; $t = "1"; $t2 = 1; $t3 = (1); echo $o->{1}; // 3 echo $o->{'1'}; // 3 echo $o->$t; // 3 echo $o->$t2; // 3 echo $o->$t3; // 3 echo $o->1; // error echo $o->(1); // error
fuente
Me temo que no está permitido nombrar objetos que comiencen con números. Cambie el nombre del primero a "448364" comenzando con una letra.
El segundo es una matriz, a las que se debe acceder mediante corchetes así:
print myVar->highlighting->test_448364->Data[0]
en lugar
fuente