php stdClass для масиву


195

У мене проблема перетворити об’єкт stdClass в масив. Я намагався таким чином:

return (array) $booking;

або

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

або

return (array) json_decode($booking);

Масив перед кастом заповнений одним записом, після моєї спроби передати його порожній. Як віддати / перетворити його, не видаляючи його рядки?

масив перед передачею:

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

після того як каст порожній NULL, якщо я спробую зробити var_dump($booking);

Я також спробував цю функцію, але завжди порожній:

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 - раніше return. І біг json_decodeпо масиву здається мені досить відчайдушним, напевно, сидіти занадто довго перед комп’ютером, і зараз пора перерватися?
хакре

Просто для уточнення: var_dump($booking);виходи NULL?
хакре

після кидаю, так, і якщо я спробую роздрукувати це: $ booking [0] ['id'] поверніть мене, що не існує
Alessandro Minoccheri

Можливо, вам буде цікаво прочитати: Як отримати корисні повідомлення про помилки в PHP? - У всякому разі, я просив, var_dump() перш ніж робити кастинг. Не використовуйте повторно те саме ім’я змінної btw. якщо $bookingдо кастингу було щось, то все-таки має бути те, що перед кастингом, а не щось інше після цього. Відмінність між вхідними та обробними змінними, інакше у вас виникають проблеми, які ви вже не розумієте, що ви там робите.
хакре

Скорочення запитання (наприклад, видалення спеціального коду функції) може бути корисним для перегляду прийнятої відповіді без прокрутки вниз
cnlevy

Відповіді:


433

Лінивий метод один вкладиша

Ви можете зробити це в одному вкладиші, використовуючи методи JSON, якщо ви готові втратити невелику ефективність роботи (хоча деякі повідомляють, що це швидше, ніж повторення через об'єкти рекурсивно - швидше за все, тому що PHP повільний при виклику функцій ). " Але я вже це зробив ", говорите ви. Не точно - ви використовували json_decodeмасив, але вам потрібно кодувати його json_encodeспочатку.

Вимоги

Методи json_encodeі json_decodeметоди. Вони автоматично вбудовуються в PHP 5.2.0 і вище. Якщо ви використовуєте будь-яку старішу версію, існує також бібліотека PECL (це означає, що в такому випадку вам слід дійсно оновити установку PHP. Підтримка 5.1 припинилася в 2006 році.)


Перетворення array/ stdClass->stdClass

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

Перетворення array/ stdClass->array

Посібник визначає другий аргумент json_decodeяк:

assoc
Коли TRUEповернуті об'єкти будуть перетворені в асоціативні масиви.

Отже, наступний рядок перетворить весь об’єкт у масив:

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

1
Якщо (array) $booking;в var_dumpце NULL(як написано OP), думаю , що цей код буде повертати?
хакре

@hakre Це не здається, що це NULLпісля того, як він буде передавати його як масив. Я думаю, що ОП означає, що це NULLвикористання, json_decode($array)яке має сенс відповідно до посібника . NULL повертається, якщо json неможливо розшифрувати
h2ooooooo

4
@AlessandroMinoccheri Причина, по якій вона не працювала раніше, була раніше, ніж ви використовували json_decode()масив. json_decodeслід використовувати на рядок JSON. Отже, якщо ми спочатку кодуємо його як рядок JSON ( json_encode), а потім розшифруємо його (використовуючи нашу рядок JSON), то це буде добре.
h2ooooooo

3
Всі забули, що ви втратите типи, які не визначені в специфікації JSON (наприклад, дати)? Тоді вам знадобиться відроджувач, якщо ви використовуєте такий підхід. Це добре лише в тому випадку, якщо у вас є базові типи, такі як числа, рядки та булеві.
Денис Пшенов

1
Чудова відповідь, я тільки що використовував json_decode ($ stdClass, правда);)
didando8a

68

використовуйте цю функцію, щоб отримати стандартний масив назад типу, який ви перебуваєте ...

return get_object_vars($booking);

19
Це не рекурсивно
gawpertron

17

Оскільки це масив, перш ніж ви його передаєте, його лиття не має сенсу.

Ви можете захотіти рекурсивну ролю, яка виглядатиме приблизно так:

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

Використання:

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

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

Результат раніше:

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

Результат після:

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

Примітка:

Тестується та працює зі складними масивами, де об'єкт stdClass може містити інші об’єкти stdClass.


Чудово. Зараз працює для об’єктів stdClass, які містять stdClass об’єкти :)
Vlad Preda

14

Будь ласка, використовуйте наступну функцію php для перетворення php stdClass в масив

get_object_vars($data)

2
Зауважте, що ця функція не є рекурсивною. Зверніться до відповіді Карло Фонтаноса щодо рекурсивного рішення.
Кортні Майлз


12

Використовуйте функціонал вбудованого типу, просто введіть

$realArray = (array)$stdClass;

1
Я віддаю перевагу цьому над json_decode / encode, набагато чистішим +1
Логан

2
Цей спосіб є більш чистим, однак він також не є рекурсивним і працює так само, як і get_object_vars (). Хоча метод json_decode / encode має відчуття зламу, він працює рекурсивно.
Деббі V

3

Просто погуглили його і знайшли тут зручну функцію, яка корисна для перетворення об’єкта 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 : Я оновив цю відповідь вмістом із пов’язаного джерела (який також тепер змінено), завдяки mason81 за те, що він запропонував мені.


1
Наступного разу, будь ласка, включіть відповідний вміст із пов’язаного джерела. Надане вами посилання змінилось і тепер не має ніякого значення і марно.
mason81

Це я шукав. Дякую тобі.

0

Ось версія відповіді Карло, яку можна використовувати в класі:

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

У наведеному нижче коді буде прочитано всі електронні листи та надрукується тема, тіло та дата.

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

Це виводить наступне:

$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 

Бореться з різними пропозиціями, я використовував пробні та помилкові рішення, щоб придумати це рішення. Сподіваюся, це допомагає.


0

Ось найкраща функція «Об’єкт для масиву» у мене - працює рекурсивно:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.