2011-01-25 9 views
25

¿Hay alguna forma de convertir un array multidimensional en un objeto stdClass en PHP?PHP - ¿Matriz recursiva al objeto?

Fundir como (object) parece no funcionar recursivamente. json_decode(json_encode($array)) produce el resultado que estoy buscando, pero tiene que haber una mejor manera ...

Respuesta

45

Por lo que yo puedo decir, no hay una solución pre-compilados para esto, por lo que sólo puede rodar su 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; 
} 
+3

Es posible que las matrices PHP tengan claves vacías, pero los objetos no pueden tener propiedades vacías. Podría valer la pena cambiar el 'else' por' elseif ($ k! == '') ' – Andy

+0

@Andy Fixed, ¡gracias! –

+0

¡Gracias por notar que no se puede hacer solo con elseif! – Andy

7
function toObject($array) { 
    $obj = new stdClass(); 
    foreach ($array as $key => $val) { 
     $obj->$key = is_array($val) ? toObject($val) : $val; 
    } 
    return $obj; 
} 
+0

Esto generará un error fatal (no se puede acceder a la propiedad vacía) para las claves vacías en la matriz. Observe [strlen en la respuesta de Jacob] (http://stackoverflow.com/questions/4790453/php-recursive-array-to-object#answer-4790485) –

30

sé esta respuesta está llegando tarde, pero lo voy a publicar para cualquier persona que esté buscando una solución.

En lugar de todo este bucle, etc., puede utilizar la función nativa json_ * de PHP. Tengo un par de funciones útiles que utilizo 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; 
} 

Hope esto puede ser útil

+2

Aprecio la publicación mejor-tarde-que-nunca, pero mi original Pregunta referida a este método. – Peter

+0

No tengo una defensa válida sobre cómo logré pasar por alto eso:/Lo único que puedo hacer es ponerme las gafas y citar a Steve Erkle; ¿¡Hice yo eso!? Volver al tema: Que yo sepa, y en mi humilde opinión, esta es la forma más limpia y óptima para hacerlo. Por favor corrígeme si estoy equivocado :) – Ole

+3

Puede ser el más limpio si estás juzgando por líneas de código, pero hay mucho más sobrecarga involucrado. La respuesta de Jacob Relkin es más eficiente y codificada con la misma facilidad. – Peter

0

Aquí hay una función para hacer una conversión profunda en el lugar-array-a objeto que usa interno de PHP (poco profundo) mecanismo de fundición de matriz a objeto. 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 utilice este código si existe el riesgo de tener referencias circulares.

3
/** 
* 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; 
} 
0

EDIT: Esta función es la conversión de un objeto a matriz.

De 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; 
} 
+0

¿Por qué $ arrObj no se devuelve si ya está listo? – guido

+0

Como entendí mal la consulta, esta fn es la conversión de objeto a matriz. Actualizaré mi respuesta. – Kamil

0

Aquí está una manera suave para hacerlo que puede manejar una matriz asociativa con gran profundidad y no sobrescribe 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); 
0

La más corta que podía llegar a:

array_walk_recursive($obj, function (&$val) { if (is_object($val)) $val = get_object_vars($val); }); 
2

Algunas de las otras soluciones publicadas aquí no dicen matrices aparte secuenciales (lo que sería [] en JS) a partir de mapas ({} en JS.) Para muchos casos de uso, es importante diferenciar las matrices PHP que tienen todas las claves numéricas secuenciales, que deberían dejarse como tales, de las matrices PHP que no tienen claves numéricas, que deberían convertirse en objetos. (Mis soluciones a continuación no están definidas para matrices que no se encuentran en las dos categorías anteriores.)

El método json_decode(json_encode($x)) maneja los dos tipos correctamente, pero no es la solución más rápida. Todavía es decente, aunque, por un total 25μs por corrida en mis datos de la muestra (un promedio de más de 1 m corre, menos la sobrecarga de bucle.)

I Benchmarked un par de variaciones del convertidor recursiva y terminó con la 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.Es relojes en 11μs por cada ejecución en mi datos de la 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í está una versión en el lugar. Puede ser más rápido en algunas datos de entrada grandes, donde sólo pequeñas partes necesitan ser convertidos, pero en mi datos de la muestra se tomó 15μs por cada 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; 
    } 
} 

Yo no probar soluciones utilizando array_walk_recursive()

+0

El primer método, acaba de crear un objeto vacío. El segundo método para mí solo logró convertir la matriz asociativa más externa en un objeto 'stdClass'. Todo lo demás internamente se mantuvo como una matriz. –

+0

@KimberlyW Acabo de probar ambos y aún funcionan en PHP 7. [Ver este ejemplo] (http://sandbox.onlinephpfunctions.com/code/4fe7ffbed29c738f928ee5e3c13aee37471420ff) – Tobia

1

tarde, pero sólo quería mencionar que se puede utilizar el JSON de codificación/decodificación para convertir completamente desde/hasta matriz:

//convert object $object into array 
$array = json_decode(json_encode($object), true); 
//convert array $array into object 
$object = json_decode(json_encode($array)); 

json_encode y json_decode funciones están disponibles a partir de PHP 5.2

+1

Esto se mencionó en la pregunta misma e incluso hay [otra respuesta de 2012] (https://stackoverflow.com/a/9185337/1218980) sobre esta misma pregunta. –

1

Puede utilizar el array_map de forma recursiva:

public static function _arrayToObject($array) { 
    return is_array($array) ? (object) array_map([__CLASS__, __METHOD__], $array) : $array; 
} 

funciona perfecto para mí ya que no expulsa los objetos de carbono ejemplo a un stdClass básica (que hace el JSON envío/recepción)

+0

Esto es simple y dulce y útil cuando necesita este tipo de utilidad dentro de una clase; referencias de los cuales son difíciles de encontrar. Deberías envolverlo en una clase de ejemplo solo por claridad. De lo contrario, buen ejemplo de la magia __CLASS__, __METHOD__ ... no la ves a menudo. – ChrisN

0
public static function _arrayToObject($array) { 
    $json = json_encode($array); 
    $object = json_decode($json); 
    return $object 
} 
Cuestiones relacionadas