php - org - mapwindows 5
¿Cómo acceder a las propiedades del objeto con nombres como enteros? (6)
Cómo acceder a un elemento de matriz asociativa de PHP cuyo resultado es:
[highlighting] => stdClass Object
(
[448364] => stdClass Object
(
[Data] => Array
(
[0] => Tax amount liability is .......
Quiero acceder al valor de cadena en la clave [0]. Quiero hacer algo como:
print myVar->highlighting->448364->Data->0
Pero los dos números / números enteros parecen ser un problema.
EDITAR:
Voy a dar un poco de historia aquí de dónde obtengo miVar. Estoy usando json_decode()
algo así como:
$myVar = json_decode(url)
Actualizado para PHP 7.2
PHP 7.2 introdujo un cambio de comportamiento para convertir claves numéricas en moldes de objetos y matrices , lo que corrige esta incoherencia particular y hace que todos los ejemplos siguientes se comporten como se esperaba.
¡Algo menos de lo que confundirse!
Respuesta original (se aplica a versiones anteriores a 7.2.0)
PHP tiene su cuota de callejones oscuros que realmente no desea encontrar dentro. Las propiedades de objetos con nombres que son números es uno de ellos ...
Lo que nunca te dijeron
Hecho n. ° 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: puede acceder a dichas propiedades con la sintaxis de llaves
$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!
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?
Bastante intuitivo, ¿no estás de acuerdo?
Lo que puedes hacer
Opción n. ° 1: hágalo manualmente
El enfoque más práctico es simplemente devolver el objeto que le interesa a 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 recursivamente. Entonces en tu caso deberías 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 a matrices recursivamente:
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, ya que lanzará innecesariamente a las matrices todas las propiedades que no le interesan, así como las que usted es.
Opción n. ° 3: jugarlo inteligentemente
Una alternativa de la opción anterior es usar las funciones incorporadas de JSON:
$arr = json_decode(json_encode($myVar), true);
$value = $arr[''highlighting''][''448364''][''Data''][''0''];
Las funciones JSON ayudan a realizar una conversión recursiva a una matriz sin la necesidad de definir ninguna función externa. Independientemente de lo deseable que parezca, tiene la desventaja "nuke" de la opción 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
).
Me temo que no puedes nombrar objetos comenzando con números. Cambia el nombre al primero "448364" que comienza con una letra.
El segundo es una matriz, a los que se debe acceder mediante corchetes de la siguiente manera:
print myVar->highlighting->test_448364->Data[0]
en lugar
Si un objeto comienza con @
como:
SimpleXMLElement Object (
[@attributes] => Array (
[href] => qwertyuiop.html
[id] => html21
[media-type] => application/xhtml+xml
)
)
Tienes que usar:
print_r($parent_object->attributes());
porque $parent_object->{''@attributes''}
o $parent_object[''@attributes'']
no funcionarán.
Solo quería agregar a la elocuente explicación de Jon la razón por la cual esto falla. Todo se debe a que, al crear una matriz, php convierte las claves en enteros, si puede, lo que causa problemas de búsqueda en las matrices que se han lanzado a los objetos, simplemente porque la clave numérica se conserva. Esto es problemático porque todas las opciones de acceso a propiedades 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 );
Cuál sería la salida:
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 cadena basada. Esta es la razón por la #Fact 4
funciona el #Fact 4
Jon, porque al establecer la propiedad usando llaves, significa que usted siempre define una clave basada en cadenas, en lugar de una numérica.
Tomando la solución de Jon, pero volviéndola en su cabeza, puede generar un objeto de su matriz que siempre tenga claves basadas en cadenas haciendo lo siguiente:
$obj = json_decode(json_encode($arr));
A partir de ahora, puede usar cualquiera de las siguientes opciones, ya que el acceso de esta manera siempre convierte el valor dentro del corral a una cadena:
$obj->{123};
$obj->{''123''};
Buen viejo ilógico PHP ...
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 convertirla después de los hechos.
Esto puede no ser adecuado para todas las aplicaciones, pero realmente me ayudó a hacer referencia fácilmente a una propiedad del objeto oroginal.
La solución se encontró en este tutorial - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
Saludos
Yo 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;
}
}
?>
- primero pase su matriz a la función
objectToArray
- luego toma el valor de retorno
- echo
[highlighting][448364][Data][0]