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

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

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)

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

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

Вот лучшая у меня функция 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);

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.