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.