php stdClass do tablicy


195

Mam problem z konwersją obiektu stdClass na tablicę. Próbowałem w ten sposób:

return (array) $booking;

lub

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

lub

return (array) json_decode($booking);

Tablica przed rzutowaniem jest pełna jednym rekordem, po mojej próbie rzutowania jest pusta. Jak rzutować / konwertować bez usuwania wierszy?

tablica przed rzutowaniem:

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

po rzuceniu jest pusty NULL, jeśli spróbuję zrobić var_dump($booking);

Próbowałem również tej funkcji, ale zawsze pusta:

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

php.net/var_dump ... php.net/var_export - wcześniej return. A bieganie json_decodepo tablicy wydaje mi się dość desperackie, prawdopodobnie siedzi zbyt długo przed komputerem, a teraz jest czas na przerwę?
hakre

Wyjaśnij: var_dump($booking);wyniki NULL?
hakre

po obsadzie tak, a jeśli spróbuję wydrukować to: $ booking [0] ['id'] zwróć mi nieistniejące
Alessandro Minoccheri

Być może zainteresuje Cię przeczytanie: Jak uzyskać przydatne komunikaty o błędach w PHP? - W każdym razie prosiłem o to var_dump() przed castingiem. Nie używaj ponownie tej samej nazwy zmiennej btw. jeśli $bookingbyło coś przed castingiem, powinno to być coś przed castowaniem, a nie coś innego później. Różnicuj między zmiennymi wejściowymi i przetwarzającymi, w przeciwnym razie napotkasz problemy, których już nie rozumiesz.
hakre

Skrócenie pytania (np. Usunięcie niestandardowego kodu funkcji) może być przydatne, aby zobaczyć zaakceptowaną odpowiedź bez konieczności przewijania w dół
cnlevy

Odpowiedzi:


432

Leniwa sposób jedna wkładka

Możesz to zrobić w jednej linijce przy użyciu metod JSON, jeśli chcesz stracić odrobinę wydajności (choć niektórzy twierdzą, że jest szybszy niż iteracja po obiektach rekurencyjnie - najprawdopodobniej dlatego, że PHP powolnie wywołuje funkcje ). „ Ale ja już to zrobiłem ”, mówisz. Nie do końca - użyłeś json_decodetablicy, ale najpierw musisz ją zakodować json_encode.

Wymagania

json_encodeI json_decodemetody. Są one automatycznie pakowane w PHP 5.2.0 i nowsze. Jeśli używasz dowolnej starszej wersji, istnieje również biblioteka PECL (która mówi, że w takim przypadku powinieneś naprawdę zaktualizować swoją instalację PHP. Obsługa 5.1 została zatrzymana w 2006 roku.)


Konwertowanie array/ stdClass->stdClass

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

Konwertowanie array/ stdClass->array

Podręcznik określa drugi argument json_decodejako:

assoc
Kiedy TRUEzwrócone obiekty zostaną przekształcone w tablice asocjacyjne.

Dlatego następujący wiersz przekształci cały obiekt w tablicę:

$array = json_decode(json_encode($booking), true);

1
Jeśli (array) $booking;w var_dumpjest NULL(jak napisane przez OP), zgadnij, co ten kod zwróci?
hakre

@hakre Nie wygląda na to, że NULLpo rzuceniu go jako tablicę. Myślę, że OP oznacza, że ​​jest NULLpo użyciu, json_decode($array)co ma sens zgodnie z instrukcją .
Wartość

4
@AlessandroMinoccheri Powodem, dla którego nie działał wcześniej, było użycie go json_decode()w tablicy. json_decodepowinien być używany w ciągu JSON. Dlatego, jeśli najpierw zakodujemy go jako ciąg JSON ( json_encode), a następnie zdekodujemy (używając naszego ciągu JSON), to będzie działał dobrze.
h2ooooooo,

3
Czy wszyscy zapomnieli, że stracisz typy, które nie są zdefiniowane w specyfikacji JSON (na przykład daty)? Będziesz musiał mieć Reviver, jeśli zastosujesz to podejście. Jest to dobre tylko wtedy, gdy masz podstawowe typy, takie jak liczby, ciągi znaków i logiczne.
Denis Pshenov

1
Świetna odpowiedź, właśnie używałem json_decode ($ stdClass, prawda);)
didando8a

68

użyj tej funkcji, aby uzyskać standardową tablicę typu, którego szukasz ...

return get_object_vars($booking);

19
To nie jest rekurencyjne
gawpertron

17

Ponieważ jest to tablica przed jej rzutowaniem, rzutowanie nie ma sensu.

Być może potrzebujesz rekurencyjnej obsady, która wyglądałaby mniej więcej tak:

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

Stosowanie:

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

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

Wynik przed:

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

Wynik po:

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

Uwaga:

Testowany i działający ze złożonymi tablicami, w których obiekt stdClass może zawierać inne obiekty stdClass.


Wspaniały. Teraz działa dla obiektów stdClass, które zawierają obiekty stdClass :)
Vlad Preda,

14

Użyj poniższej funkcji php do konwersji phd stdClass na tablicę

get_object_vars($data)

2
Pamiętaj, że ta funkcja nie jest rekurencyjna. Zobacz odpowiedź Carlo Fontanosa na rekurencyjne rozwiązanie.
Courtney Miles,


12

Skorzystaj z wbudowanej funkcji rzutowania typu, po prostu pisz

$realArray = (array)$stdClass;

1
Wolę to niż json_decode / encode, znacznie czystsze +1
Logan

2
Ta metoda jest czystsza, jednak nie jest również rekurencyjna i działa tak samo, jak get_object_vars (). Chociaż metoda json_decode / encode działa jak hack, działa rekurencyjnie.
Debbie V

3

Po prostu google go i znalazłem tutaj przydatną funkcję, która jest przydatna do konwersji obiektu stdClass na tablicę rekurencyjnie.

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

EDYCJA : Zaktualizowałem tę odpowiedź treściami z połączonego źródła (które również zostało zmienione), dzięki mason81 za sugestie.


1
Następnym razem dołącz odpowiednią treść z połączonego źródła. Podany link zmienił się i jest teraz nieistotny i bezużyteczny.
mason81

Tego właśnie szukałem. Dziękuję bardzo.

0

Oto wersja odpowiedzi Carlo, którą można wykorzystać w klasie:

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

0

Poniższy kod przeczyta wszystkie e-maile i wydrukuje temat, treść i datę.

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

To powoduje, że:

$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 

Po zmaganiu się z różnymi sugestiami skorzystałem z metody prób i błędów, aby znaleźć to rozwiązanie. Mam nadzieję, że to pomoże.


0

Oto najlepsza funkcja Object to Array, jaką mam - działa rekurencyjnie:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.