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с массивом мне кажется довольно отчаянным, вероятно, слишком долго сидеть перед компьютером, и теперь пришло время сделать перерыв?
13
Просто чтобы уточнить: var_dump($booking);выходы NULL?
13
после приведения да и если я попытаюсь напечатать это: $ booking [0] ['id'] верните мне несуществующее
Alessandro Minoccheri
Возможно, вам будет интересно прочитать: Как получить полезные сообщения об ошибках в PHP? - Во всяком случае, я просил var_dump() перед кастингом. Не используйте повторно одно и то же имя переменной. если $bookingчто-то было до кастинга, то все равно должно быть что-то до кастинга, а не что-то другое после. Различие между входными и обрабатывающими переменными, иначе вы столкнетесь с проблемами, которые вы больше не понимаете, что вы там делаете.
13
Сокращение вопроса (например, удаление кода пользовательской функции) может быть полезно, чтобы увидеть принятый ответ без необходимости прокрутки вниз
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);
h2ooooooo
источник
1
Если (array) $booking;в a var_dumpесть NULL(как написано OP), угадайте, что этот код вернет?
13
@hakre Не похоже, что это NULLпосле того, как он был преобразован в массив. Я думаю, что OP означает, что это 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, true);)
didando8a
68

используйте эту функцию, чтобы получить стандартный массив того типа, который вы хотите после ...

return get_object_vars($booking);
robzero
источник
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 :)
Влад Преда
14

Пожалуйста, используйте следующую функцию php для преобразования php stdClass в массив

get_object_vars($data)
Nalantha
источник
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;
 }
}
?>

РЕДАКТИРОВАТЬ : я обновил этот ответ с содержанием из связанного источника (который также изменился сейчас), спасибо 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;
    }
}
Loren
источник
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 

Поработав с различными предложениями, я использовал метод проб и ошибок, чтобы придумать это решение. Надеюсь, поможет.

walter1957
источник
0

Вот лучшая у меня функция Object to Array - работает рекурсивно:

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
источник