php stdClass a array

195

Tengo un problema para convertir un objeto stdClass en matriz. He intentado de esta manera:

return (array) $booking;

o

return (array) json_decode($booking,true);

o

return (array) json_decode($booking);

La matriz antes del lanzamiento está llena con un registro, después de mi intento de lanzarlo está vacío. ¿Cómo emitirlo / convertirlo sin eliminar sus filas?

matriz antes del lanzamiento:

array(1) {   [0]=>   object(stdClass)#23 (36) {     ["id"]=>     string(1) "2"     ["name"]=>     string(0) ""     ["code"]=>     string(5) "56/13"   } } 

después de emitir está vacío NULL si intento hacer un var_dump($booking);

También probé esta función pero siempre está vacía:

public 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;
        }
    }
Alessandro Minoccheri
fuente
php.net/var_dump ... php.net/var_export - antes return. ¿Y correr json_decodeen una matriz me parece bastante desesperado, probablemente sentado demasiado tiempo frente a la computadora y ahora es el momento de tomar un descanso?
Hakre
Solo para aclarar: ¿ var_dump($booking);productos NULL?
Hakre
después del reparto sí, y si intento imprimir esto: $ booking [0] ['id']
devuélveme
Quizás le interese leer: ¿Cómo obtener mensajes de error útiles en PHP? - De todos modos, estaba preguntando var_dump() antes de lanzar. No reutilice el mismo nombre de variable por cierto. si $bookingera algo antes del lanzamiento, aún debería ser ese algo antes del lanzamiento y no algo diferente después. Diferir entre las variables de entrada y procesamiento, de lo contrario, se encontrará con problemas que ya no comprende lo que hace allí.
Hakre
El acortamiento de la cuestión (como quitar el código de función personalizada) podría ser útil para ver la respuesta aceptada sin tener que desplazarse hacia abajo
cnlevy

Respuestas:

432

El método perezoso de una sola línea

Puede hacer esto en una línea usando los métodos JSON si está dispuesto a perder un poco de rendimiento (aunque algunos han informado que es más rápido que iterar a través de los objetos de forma recursiva, muy probablemente porque PHP es lento en las funciones de llamada ). " Pero ya hice esto ", dices. No exactamente: lo usó json_decodeen la matriz, pero json_encodeprimero debe codificarlo .

Requisitos

El json_encodey los json_decodemétodos. Estos se incluyen automáticamente en PHP 5.2.0 y versiones posteriores. Si usa cualquier versión anterior, también hay una biblioteca PECL (dicho esto, en ese caso realmente debería actualizar su instalación de PHP. El soporte para 5.1 se detuvo en 2006).


Convertir un array/ stdClass->stdClass

$stdClass = json_decode(json_encode($booking));

Convertir un array/ stdClass->array

El manual especifica el segundo argumento de json_decodecomo:

assoc
When TRUE, los objetos devueltos se convertirán en matrices asociativas.

Por lo tanto, la siguiente línea convertirá todo su objeto en una matriz:

$array = json_decode(json_encode($booking), true);
h2ooooooo
fuente
1
Si (array) $booking;en un var_dumpes NULL(como está escrito por OP), ¿adivina qué devolverá este código?
Hakre
@hakre No parece que sea NULLdespués de lanzarlo como una matriz. Creo que OP significa que es NULLdespués de usar lo json_decode($array)que tiene sentido según el manual . Se devuelve NULL si no se puede decodificar el json
h2ooooooo
44
@AlessandroMinoccheri La razón por la que no funcionó antes fue antes de que estuviera usando json_decode()una matriz. json_decodedebe usarse en una cadena JSON. Por lo tanto, si primero lo codificamos como una cadena JSON ( json_encode) y luego lo decodificamos (usando nuestra cadena JSON), entonces funciona bien.
h2ooooooo
3
¿Han olvidado todos que perderán sus tipos que no están definidos en las especificaciones JSON (fechas, por ejemplo)? Necesitarás tener un revividor si usas este enfoque. Esto solo es bueno si tiene tipos básicos como números, cadenas y booleanos.
Denis Pshenov
1
Gran respuesta, he estado usando json_decode ($ stdClass, true);)
didando8a
68

use esta función para obtener una matriz estándar del tipo que busca ...

return get_object_vars($booking);
robzero
fuente
19
Esto no es recursivo
gawpertron
17

Dado que es una matriz antes de lanzarlo, lanzarlo no tiene sentido.

Es posible que desee un reparto recursivo, que se vería así:

function arrayCastRecursive($array)
{
    if (is_array($array)) {
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $array[$key] = arrayCastRecursive($value);
            }
            if ($value instanceof stdClass) {
                $array[$key] = arrayCastRecursive((array)$value);
            }
        }
    }
    if ($array instanceof stdClass) {
        return arrayCastRecursive((array)$array);
    }
    return $array;
}

Uso:

$obj = new stdClass;
$obj->aaa = 'asdf';
$obj->bbb = 'adsf43';
$arr = array('asdf', array($obj, 3));

var_dump($arr);
$arr = arrayCastRecursive($arr);
var_dump($arr);

Resultado anterior:

array
    0 => string 'asdf' (length = 4)
  1 => 
    array
        0 =>
        object(stdClass)[1]
          public 'aaa' => string 'asdf' (length = 4)
          public 'bbb' => string 'adsf43' (length = 6)
      1 => int 3

Resultado después de:

array
    0 => string 'asdf' (length = 4)
  1 => 
    array
        0 =>
        array
          'aaa' => string 'asdf' (length = 4)
          'bbb' => string 'adsf43' (length = 6)
      1 => int 3

Nota:

Probado y trabajando con matrices complejas donde un objeto stdClass puede contener otros objetos stdClass.

Vlad Preda
fuente
Excelente. Ahora funciona para objetos stdClass que contienen objetos stdClass :)
Vlad Preda
14

Utilice la siguiente función php para convertir php stdClass a array

get_object_vars($data)
Nalantha
fuente
2
Tenga en cuenta que esta función no es recursiva. Consulte la respuesta de Carlo Fontanos para una solución recursiva.
Courtney Miles el
12

Utilice la funcionalidad integrada de conversión de texto, simplemente escriba

$realArray = (array)$stdClass;
David Clews
fuente
1
Prefiero esto sobre json_decode / encode, mucho más limpio +1
Logan
2
Este método es más limpio, sin embargo, tampoco es recursivo y funciona igual que get_object_vars (). Si bien el método json_decode / encode tiene la sensación de un hack, funciona de forma recursiva.
Debbie V
3

Simplemente busqué en Google y encontré aquí una función útil que es útil para convertir el objeto stdClass en una matriz de forma recursiva.

<?php
function object_to_array($object) {
 if (is_object($object)) {
  return array_map(__FUNCTION__, get_object_vars($object));
 } else if (is_array($object)) {
  return array_map(__FUNCTION__, $object);
 } else {
  return $object;
 }
}
?>

EDITAR : Actualicé esta respuesta con contenido de fuente vinculada (que también se ha cambiado ahora), gracias a mason81 por sugerirme.

shasi kanth
fuente
1
La próxima vez, incluya el contenido relevante de la fuente vinculada. El enlace que proporcionó ha cambiado y ahora es irrelevante e inútil.
mason81
Esto es lo que estaba buscando, muchas gracias.
0

Aquí hay una versión de la respuesta de Carlo que se puede usar en una clase:

class Formatter
{
    public function objectToArray($data)
    {
        if (is_object($data)) {
            $data = get_object_vars($data);
        }

        if (is_array($data)) {
            return array_map(array($this, 'objectToArray'), $data);
        }

        return $data;
    }
}
Loren
fuente
0

El siguiente código leerá todos los correos electrónicos e imprimirá el Asunto, el Cuerpo y la Fecha.

<?php
  $imap=imap_open("Mailbox","Email Address","Password");
  if($imap){$fixMessages=1+imap_num_msg($imap);  //Check no.of.msgs
/*
By adding 1 to "imap_num_msg($imap)" & starting at $count=1
   the "Start" & "End" non-messages are ignored
*/
    for ($count=1; $count<$fixMessages; $count++){
      $objectOverview=imap_fetch_overview($imap,$count,0);
print '<br>$objectOverview: '; print_r($objectOverview);
print '<br>objectSubject ='.($objectOverview[0]->subject));
print '<br>objectDate ='.($objectOverview[0]->date);
      $bodyMessage=imap_fetchbody($imap,$count,1);
print '<br>bodyMessage ='.$bodyMessage.'<br><br>';
    }  //for ($count=1; $count<$fixMessages; $count++)
  }  //if($imap)
  imap_close($imap);
?>

Esto genera lo siguiente:

$objectOverview: Array ( [0] => stdClass Object ( [subject] => Hello
[from] => Email Address [to] => Email Address [date] => Sun, 16 Jul 2017 20:23:18 +0100
[message_id] =>  [size] => 741 [uid] => 2 [msgno] => 2 [recent] => 0 [flagged] => 0 
[answered] => 0 [deleted] => 0 [seen] => 1 [draft] => 0 [udate] => 1500232998 ) )
objectSubject =Hello
objectDate =Sun, 16 Jul 2017 20:23:18 +0100
bodyMessage =Test 

Habiendo luchado con varias sugerencias, he usado prueba y error para llegar a esta solución. Espero eso ayude.

walter1957
fuente
0

Aquí está la mejor función Object to Array que tengo: funciona de forma recursiva:

function object_to_array($obj, &$arr){

    if(!is_object($obj) && !is_array($obj)){
        $arr = $obj;
        return $arr;
    }

    foreach ($obj as $key => $value)
    {
        if (!empty($value))
        {
            $arr[$key] = array();
            object_to_array_v2($value, $arr[$key]);
        }
        else
        {
            $arr[$key] = $value;
        }
    }
    return $arr;
}

$ clean_array = object_to_array ($ object_data_here);

nsdb
fuente