php stdClass để mảng


195

Tôi có một vấn đề để chuyển đổi một đối tượng stdClass thành mảng. Tôi đã thử theo cách này:

return (array) $booking;

hoặc là

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

hoặc là

return (array) json_decode($booking);

Mảng trước khi diễn viên đã đầy với một bản ghi, sau khi tôi cố gắng sử dụng thì nó trống. Làm thế nào để truyền / chuyển đổi nó mà không xóa các hàng của nó?

mảng trước khi cast:

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

sau khi cast là NULL trống nếu tôi cố gắng thực hiện var_dump($booking);

Tôi cũng đã thử chức năng này nhưng luôn trống:

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 - trước đây return. Và chạy json_decodetrên một mảng có vẻ khá tuyệt vọng đối với tôi, có lẽ ngồi quá lâu trước máy tính và giờ là lúc để nghỉ ngơi?
hakre

Chỉ cần làm rõ: var_dump($booking);đầu ra NULL?
hakre

sau khi bỏ có, và nếu tôi cố in điều này: $ booking [0] ['id'] hãy trả lại cho tôi cái không tồn tại
Alessandro Minoccheri

Bạn có thể muốn đọc: Làm thế nào để có được các thông báo lỗi hữu ích trong PHP? - Dù sao, tôi đã yêu cầu var_dump() trước khi đúc. Không sử dụng lại cùng tên biến btw. nếu $bookinglà một cái gì đó trước khi đúc, nó vẫn nên là một cái gì đó trước khi đúc và không phải là một cái gì đó khác nhau sau đó. Khác nhau giữa các biến đầu vào và xử lý nếu không bạn gặp phải các vấn đề mà bạn không còn hiểu những gì bạn làm ở đó nữa.
hakre

Việc rút ngắn câu hỏi (như xóa mã chức năng tùy chỉnh) có thể hữu ích để xem câu trả lời được chấp nhận mà không cần phải cuộn xuống
cnlevy

Câu trả lời:


432

Các lười biếng phương pháp one-liner

Bạn có thể thực hiện điều này trong một lớp lót bằng các phương thức JSON nếu bạn sẵn sàng mất một chút hiệu năng (mặc dù một số người đã báo cáo rằng nó nhanh hơn việc lặp qua các đối tượng theo cách đệ quy - rất có thể là do PHP chậm trong các hàm gọi ). " Nhưng tôi đã làm điều này ", bạn nói. Không chính xác - bạn đã sử dụng json_decodetrên mảng, nhưng trước tiên bạn cần mã hóa nó json_encode.

Yêu cầu

Các json_encodejson_decodephương pháp. Chúng được tự động đóng gói trong PHP 5.2.0 trở lên. Nếu bạn sử dụng bất kỳ phiên bản cũ nào thì cũng có thư viện PECL (trong trường hợp đó, bạn thực sự nên cập nhật cài đặt PHP của mình. Hỗ trợ cho 5.1 đã dừng vào năm 2006.)


Chuyển đổi một array/ stdClass->stdClass

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

Chuyển đổi một array/ stdClass->array

Hướng dẫn chỉ định đối số thứ hai json_decodelà:

PGS
Khi TRUE, các đối tượng trả về sẽ được chuyển đổi thành các mảng kết hợp.

Do đó dòng sau sẽ chuyển đổi toàn bộ đối tượng của bạn thành một mảng:

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

1
Nếu (array) $booking;trong a var_dumpNULL(như được viết bởi OP), hãy đoán xem mã này sẽ trả về cái gì?
hakre

@hakre Có vẻ như không phải NULLsau khi đúc nó thành một mảng. Tôi nghĩ OP có nghĩa là NULLsau khi sử dụng json_decode($array)nó có ý nghĩa theo hướng dẫn . NULL được trả về nếu json không thể được giải mã
h2ooooooo

4
@AlessandroMinoccheri Lý do nó không hoạt động trước đó là trước khi bạn sử dụng json_decode()trên một mảng. json_decodenên được sử dụng trên chuỗi JSON. Do đó, nếu chúng ta mã hóa nó dưới dạng chuỗi JSON trước ( json_encode) và sau đó giải mã nó (sử dụng chuỗi JSON của chúng tôi), thì nó hoạt động tốt.
h2ooooooo

3
Có phải mọi người đã quên rằng bạn sẽ mất các loại không được xác định trong thông số JSON (ví dụ: ngày)? Bạn sẽ cần phải có một reviver sau đó nếu bạn sử dụng phương pháp này. Điều này chỉ tốt nếu bạn có các loại cơ bản như số, chuỗi và booleans.
Denis Pshenov

1
Câu trả lời tuyệt vời, tôi vừa mới sử dụng json_decode ($ stdClass, đúng);)
didando8a

68

sử dụng chức năng này để lấy lại một mảng tiêu chuẩn của loại bạn đang theo sau ...

return get_object_vars($booking);

19
Đây không phải là đệ quy
gawpertron 18/03/2016

17

Vì nó là một mảng trước khi bạn đúc nó, nên nó không có ý nghĩa gì.

Bạn có thể muốn một diễn viên đệ quy, trông giống như thế này:

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

Sử dụng:

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

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

Kết quả trước:

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

Kết quả sau:

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

Ghi chú:

Đã thử nghiệm và làm việc với các mảng phức tạp trong đó một đối tượng stdClass có thể chứa các đối tượng stdClass khác.


Tuyệt quá. Bây giờ hoạt động cho các đối tượng stdClass có chứa các đối tượng stdClass :)
Vlad Preda

14

Vui lòng sử dụng hàm php sau để chuyển đổi php stdClass thành mảng

get_object_vars($data)

2
Lưu ý rằng chức năng này không được đệ quy. Tham khảo câu trả lời của Carlo Fontanos cho một giải pháp đệ quy.
Courtney Miles


12

Sử dụng chức năng đúc kiểu tích hợp, chỉ cần gõ

$realArray = (array)$stdClass;

1
Tôi thích cái này hơn json_decode / encode, sạch hơn nhiều +1
Logan

2
Phương thức này sạch hơn, tuy nhiên, nó cũng không đệ quy và hoạt động tương tự như get_object_vars (). Trong khi phương thức json_decode / encode có cảm giác hack, nó hoạt động đệ quy.
Debbie V

3

Chỉ cần googled nó, và tìm thấy ở đây một hàm tiện dụng rất hữu ích để chuyển đổi đối tượng stdClass thành mảng đệ quy.

<?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 : Tôi đã cập nhật câu trả lời này với nội dung từ nguồn được liên kết (hiện cũng đã thay đổi), nhờ mason81 đã gợi ý cho tôi.


1
Lần tới, vui lòng bao gồm các nội dung liên quan từ nguồn được liên kết. Liên kết bạn cung cấp đã thay đổi và hiện không liên quan và vô dụng.
mason81

Đây là những gì tôi đang tìm kiếm, Cảm ơn bạn rất nhiều.

0

Đây là phiên bản câu trả lời của Carlo có thể được sử dụng trong một lớp:

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

Đoạn mã sau sẽ đọc tất cả các email và in Chủ đề, Nội dung & Ngày.

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

Điều này xuất ra như sau:

$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 

Khi phải vật lộn với nhiều đề xuất khác nhau, tôi đã sử dụng thử & lỗi để đưa ra giải pháp này. Hy vọng nó giúp.


0

Đây là hàm Object to Array tốt nhất mà tôi có - hoạt động đệ quy:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.