recorrer - PHP-¿Matriz recursiva a Object?
recorrer stdclass object php (13)
Algunas de las otras soluciones publicadas aquí no distinguen las matrices secuenciales (lo que sería []
en JS) de los mapas ( {}
en JS). Para muchos casos de uso es importante diferenciar las matrices PHP que tienen todas las claves numéricas secuenciales, que debería dejarse como tal, a partir de matrices PHP que no tienen claves numéricas, que deberían convertirse en objetos. (Mis soluciones a continuación no están definidas para las matrices que no se encuentran en las dos categorías anteriores).
El json_decode(json_encode($x))
maneja los dos tipos correctamente, pero no es la solución más rápida. Sin embargo, sigue siendo decente, con un total de 25 μs por ejecución en mis datos de muestra (promediada sobre 1M de ejecución, menos la sobrecarga del ciclo).
Analicé un par de variaciones del convertidor recursivo y terminé con lo siguiente. Reconstruye todas las matrices y objetos (realizando una copia profunda) pero parece ser más rápido que las soluciones alternativas que modifican las matrices en su lugar. Registra a 11 μs por ejecución en mis datos de muestra:
function array_to_object($x) {
if (!is_array($x)) {
return $x;
} elseif (is_numeric(key($x))) {
return array_map(__FUNCTION__, $x);
} else {
return (object) array_map(__FUNCTION__, $x);
}
}
Aquí hay una versión local. Puede ser más rápido en algunos datos de entrada grandes donde solo se deben convertir partes pequeñas, pero en mis datos de muestra se necesitaron 15 μs por ejecución:
function array_to_object_inplace(&$x) {
if (!is_array($x)) {
return;
}
array_walk($x, __FUNCTION__);
reset($x);
if (!is_numeric(key($x))) {
$x = (object) $x;
}
}
No probé soluciones usando array_walk_recursive()
¿Hay alguna forma de convertir una array
multidimensional a un objeto stdClass
en PHP?
Casting como (object)
no parece funcionar recursivamente. json_decode(json_encode($array))
produce el resultado que estoy buscando, pero tiene que haber una mejor manera ...
Esta es una forma sencilla de hacerlo que puede manejar una matriz asociativa con gran profundidad y no sobrescribe las propiedades de los objetos que no están en la matriz.
<?php
function setPropsViaArray( $a, $o )
{
foreach ( $a as $k => $v )
{
if ( is_array( $v ) )
{
$o->{$k} = setPropsViaArray( $v, ! empty ( $o->{$k} ) ? $o->{$k} : new stdClass() );
}
else
{
$o->{$k} = $v;
}
}
return $o;
};
setPropsViaArray( $newArrayData, $existingObject );
Esta es una función para realizar una conversión profunda de matriz a objeto en el lugar que utiliza el mecanismo de conversión de tipo de matriz a objeto interna (poco profunda) de PHP. Crea nuevos objetos solo cuando es necesario, minimizando la duplicación de datos.
function toObject($array) {
foreach ($array as $key=>$value)
if (is_array($value))
$array[$key] = toObject($value);
return (object)$array;
}
Advertencia: no use este código si existe el riesgo de tener referencias circulares.
La forma más sencilla de convertir una matriz asociativa en objeto es:
Primero codifícalo en json, luego decodifícalo.
como $objectArray = json_decode(json_encode($associtiveArray));
Lo más corto que pude encontrar fue:
array_walk_recursive($obj, function (&$val) { if (is_object($val)) $val = get_object_vars($val); });
Por lo que puedo decir, no hay una solución precompilada para esto, así que solo puedes hacer tu propia:
function array_to_object($array) {
$obj = new stdClass;
foreach($array as $k => $v) {
if(strlen($k)) {
if(is_array($v)) {
$obj->{$k} = array_to_object($v); //RECURSION
} else {
$obj->{$k} = $v;
}
}
}
return $obj;
}
Puedes usar el array_map
recursivamente:
public static function _arrayToObject($array) {
return is_array($array) ? (object) array_map([__CLASS__, __METHOD__], $array) : $array;
}
Funciona perfecto para mí, ya que no emite, por ejemplo, objetos de carbono a un stdClass básico (que el json codifica / decodifica)
Sé que esta respuesta llega tarde, pero la publicaré para cualquiera que esté buscando una solución.
En lugar de todo este bucle, etc., puede usar la función json_ * nativa de PHP. Tengo un par de funciones útiles que uso mucho
/**
* Convert an array into a stdClass()
*
* @param array $array The array we want to convert
*
* @return object
*/
function arrayToObject($array)
{
// First we convert the array to a json string
$json = json_encode($array);
// The we convert the json string to a stdClass()
$object = json_decode($json);
return $object;
}
/**
* Convert a object to an array
*
* @param object $object The object we want to convert
*
* @return array
*/
function objectToArray($object)
{
// First we convert the object into a json string
$json = json_encode($object);
// Then we convert the json string to an array
$array = json_decode($json, true);
return $array;
}
Espero que esto puede ser útil
Tarde, pero solo quería mencionar que puede usar la codificación / decodificación JSON para convertir completamente de / a matriz:
//convert object $object into array
$array = json_decode(json_encode($object), true);
//convert array $array into object
$object = json_decode(json_encode($array));
Las funciones json_encode y json_decode están disponibles a partir de php 5.2
EDITAR: Esta función es la conversión de un objeto a una matriz.
Desde https://forrst.com/posts/PHP_Recursive_Object_to_Array_good_for_handling-0ka
protected function object_to_array($obj)
{
$arrObj = is_object($obj) ? get_object_vars($obj) : $obj;
foreach ($arrObj as $key => $val) {
$val = (is_array($val) || is_object($val)) ? $this->object_to_array($val) : $val;
$arr[$key] = $val;
}
return $arr;
}
/**
* Recursively converts associative arrays to stdClass while keeping integer keys subarrays as arrays
* (lists of scalar values or collection of objects).
*/
function a2o( array $array ) {
$resultObj = new /stdClass;
$resultArr = array();
$hasIntKeys = false;
$hasStrKeys = false;
foreach ( $array as $k => $v ) {
if ( !$hasIntKeys ) {
$hasIntKeys = is_int( $k );
}
if ( !$hasStrKeys ) {
$hasStrKeys = is_string( $k );
}
if ( $hasIntKeys && $hasStrKeys ) {
$e = new /Exception( ''Current level has both integer and string keys, thus it is impossible to keep array or convert to object'' );
$e->vars = array( ''level'' => $array );
throw $e;
}
if ( $hasStrKeys ) {
$resultObj->{$k} = is_array( $v ) ? a2o( $v ) : $v;
} else {
$resultArr[$k] = is_array( $v ) ? a2o( $v ) : $v;
}
}
return ($hasStrKeys) ? $resultObj : $resultArr;
}
function toObject($array) {
$obj = new stdClass();
foreach ($array as $key => $val) {
$obj->$key = is_array($val) ? toObject($val) : $val;
}
return $obj;
}
public static function _arrayToObject($array) {
$json = json_encode($array);
$object = json_decode($json);
return $object
}