php stdClass para array

195

Eu tenho um problema para converter um objeto stdClass em matriz. Eu tentei desta maneira:

return (array) $booking;

ou

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

ou

return (array) json_decode($booking);

A matriz antes do elenco está cheia com um registro, depois que minha tentativa de elenco estiver vazia. Como converter / converter sem excluir suas linhas?

matriz antes do lançamento:

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

depois que o elenco estiver vazio NULL se eu tentar fazer uma var_dump($booking);

Eu também tentei esta função, mas sempre vazio:

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
fonte
php.net/var_dump ... php.net/var_export - antes return. E rodar json_decodeem uma matriz parece bastante desesperador para mim, provavelmente sentado demais na frente do computador e agora é hora de fazer uma pausa?
hakre
Apenas para esclarecer: var_dump($booking);saídas NULL?
hakre
depois sim elenco, e se eu tentar imprimir esta: $ reserva [0] [ 'id'] me voltar que não existe
Alessandro Minoccheri
Você pode estar interessado em ler: Como obter mensagens de erro úteis em PHP? - Enfim, eu estava perguntando var_dump() antes de lançar. Não reutilize o mesmo nome de variável btw. se $bookinghavia algo antes do lançamento, ainda deve ser algo antes do lançamento e não algo diferente depois. Diferir entre as variáveis ​​de entrada e de processamento, caso contrário, você terá problemas que não entenderão mais o que faz lá.
hakre
Encurtando a questão (como a remoção do código de função personalizada) poderia ser útil para ver a resposta aceita sem ter que rolar para baixo
cnlevy

Respostas:

432

O método preguiçoso de uma linha

Você pode fazer isso em uma linha usando os métodos JSON, se estiver disposto a perder um pouquinho de desempenho (embora alguns tenham relatado que é mais rápido do que repetindo os objetos de forma recursiva - provavelmente porque o PHP é lento em chamar funções ). " Mas eu já fiz isso ", você diz. Não exatamente - você usou json_decodena matriz, mas precisa codificá-la json_encodeprimeiro.

Exigências

A json_encodee json_decodemétodos. Estes são agrupados automaticamente no PHP 5.2.0 e posterior. Se você usa qualquer versão mais antiga, há também uma biblioteca PECL (ou seja, nesse caso, você deve realmente atualizar sua instalação do PHP. O suporte para 5.1 parou em 2006.)


Convertendo um array/ stdClass->stdClass

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

Convertendo um array/ stdClass->array

O manual especifica o segundo argumento de json_decode:

assoc
Quando TRUE, os objetos retornados serão convertidos em matrizes associativas.

Portanto, a seguinte linha converterá todo o objeto em uma matriz:

$array = json_decode(json_encode($booking), true);
h2ooooooo
fonte
1
Se (array) $booking;em um var_dumpé NULL(conforme escrito pelo OP), adivinhe o que esse código retornará?
hakre 02/09
@ hakre Não parece que foi NULLdepois de lançá-lo como uma matriz. Eu acho que OP significa que é NULLdepois de usar o json_decode($array)que faz sentido de acordo com o manual . NULL é retornado se o json não puder ser decodificado.
h2ooooooo
4
@AlessandroMinoccheri A razão pela qual não funcionou antes foi antes de você estar usando json_decode()uma matriz. json_decodedeve ser usado em uma sequência JSON. Portanto, se a codificarmos como uma string JSON primeiro ( json_encode) e depois a decodificar (usando nossa string JSON), funcionará bem.
H2ooooooo 02/09
3
Todo mundo esqueceu que você perderá seus tipos que não estão definidos na especificação JSON (datas por exemplo)? Você precisará de um reviver, se usar essa abordagem. Isso só é bom se você tiver tipos básicos, como números, strings e booleanos.
Denis Pshenov 03/11
1
Ótima resposta, eu estou apenas usando json_decode ($ stdClass, true);) #
didando8a
68

use esta função para obter uma matriz padrão de volta do tipo que você procura ...

return get_object_vars($booking);
robzero
fonte
19
Este não é recursiva
gawpertron
17

Como é uma matriz antes da transmissão, a transmissão não faz sentido.

Você pode querer um elenco recursivo, que seria algo como isto:

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 antes:

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 após:

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

Nota:

Testado e trabalhando com matrizes complexas em que um objeto stdClass pode conter outros objetos stdClass.

Vlad Preda
fonte
Ótimo. Agora funciona para objetos stdClass que contêm objetos stdClass :)
Vlad Preda
14

Por favor, use a seguinte função php para converter php stdClass em array

get_object_vars($data)
Nalantha
fonte
2
Observe que esta função não é recursiva. Consulte a resposta de Carlo Fontanos para uma solução recursiva.
Courtney Miles
12

Use a funcionalidade de conversão de tipo incorporada, basta digitar

$realArray = (array)$stdClass;
David Clews
fonte
1
Eu prefiro isso sobre json_decode / codificar, muito mais limpo +1
Logan
2
Este método é mais limpo, no entanto, também não é recursivo e funciona da mesma maneira que o get_object_vars (). Embora o método json_decode / encode pareça um hack, ele funciona recursivamente.
Debbie V
3

Apenas pesquisei no Google e encontrei aqui uma função útil que é útil para converter recursivamente o objeto stdClass.

<?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;
 }
}
?>

EDIT : Atualizei esta resposta com o conteúdo da fonte vinculada (que também foi alterada agora), graças a mason81 por me sugerir.

shasi kanth
fonte
1
Da próxima vez, inclua o conteúdo relevante da fonte vinculada. O link que você forneceu mudou e agora é irrelevante e inútil.
mason81
Era isso que eu estava procurando, muito obrigado.
0

Aqui está uma versão da resposta de Carlo que pode ser usada em uma classe:

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
fonte
0

O código a seguir irá ler todos os e-mails e imprimir Assunto, Corpo e Data.

<?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);
?>

Isso gera o seguinte:

$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 

Tendo lutado com várias sugestões, usei tentativa e erro para encontrar esta solução. Espero que ajude.

walter1957
fonte
0

Aqui está a melhor função Object to Array que eu tenho - funciona recursivamente:

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
fonte