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บนอาเรย์นั้นค่อนข้างหมดหวังสำหรับฉันอาจจะนั่งอยู่หน้าคอมพิวเตอร์นานเกินไปและถึงเวลาพักแล้ว
hakre

เพียงชี้แจง: var_dump($booking);ผลผลิตNULL?
hakre

หลังจากโยนใช่และถ้าฉันพยายามที่จะพิมพ์นี้: $ booking [0] ['id'] ส่งคืนฉันที่ไม่มีอยู่
Alessandro Minoccheri

คุณอาจสนใจที่จะอ่าน: วิธีรับข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์ใน PHP? - อย่างไรก็ตามฉันถูกขอvar_dump() ก่อนที่จะคัดเลือก ห้ามใช้ชื่อตัวแปรเดียวกันอีกครั้ง btw ถ้า$bookingเป็นอะไรบางอย่างก่อนการคัดเลือกนักแสดงมันควรจะเป็นอย่างนั้นก่อนที่จะทำการคัดเลือกนักแสดง แตกต่างระหว่างตัวแปรอินพุตและการประมวลผลมิฉะนั้นคุณจะพบปัญหาที่คุณไม่เข้าใจอีกต่อไปว่าคุณทำอะไรอยู่ที่นั่น
hakre

การย่อคำถาม (เช่นการลบรหัสฟังก์ชันที่กำหนดเอง) อาจเป็นประโยชน์ในการดูคำตอบที่ยอมรับได้โดยไม่ต้องเลื่อนลง
cnlevy

คำตอบ:


433

ขี้เกียจวิธีหนึ่งซับ

คุณสามารถทำสิ่งนี้ในหนึ่งสายการบินโดยใช้วิธีการ JSON ถ้าคุณเต็มใจที่จะสูญเสียประสิทธิภาพเล็กน้อย (แม้ว่าบางคนรายงานว่ามันเร็วกว่าการวนซ้ำผ่านวัตถุแบบเรียกซ้ำ - ส่วนใหญ่เป็นเพราะ PHP ทำงานช้าที่เรียก ) " แต่ฉันทำสิ่งนี้แล้ว " คุณพูด ไม่ถูกต้อง - คุณใช้json_decodeกับอาร์เรย์ แต่คุณต้องเข้ารหัสjson_encodeก่อน

ความต้องการ

json_encodeและjson_decodeวิธีการ สิ่งเหล่านี้รวมอยู่ใน PHP 5.2.0 ขึ้นไปโดยอัตโนมัติ หากคุณใช้เวอร์ชั่นเก่ากว่านี้ก็มีห้องสมุด PECL (เช่นที่กล่าวไว้ในกรณีนี้คุณควรอัปเดตการติดตั้ง PHP ของคุณจริงๆการสนับสนุน 5.1 หยุดลงในปี 2549)


การแปลง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) ให้เดาว่ารหัสนี้จะส่งคืนอย่างไร
hakre

@ ฮาเครมันดูไม่เหมือนว่าNULLหลังจากหล่อมันเป็นอาเรย์แล้ว ผมคิดว่า OP หมายความว่ามันเป็นNULLหลังจากที่ใช้json_decode($array)ซึ่งจะทำให้ความรู้สึกต่อคู่มือ NULL ถูกส่งคืนถ้า json ไม่สามารถถอดรหัสได้
h2ooooooo

4
@AlessandroMinoccheri เหตุผลที่มันไม่ทำงานมาก่อนคือก่อนที่คุณจะใช้json_decode()ในอาร์เรย์ json_decodeควรใช้กับสตริง JSON ดังนั้นถ้าเราเข้ารหัสมันเป็นสตริง JSON ก่อน ( json_encode) แล้วถอดรหัสมัน (โดยใช้สตริง JSON ของเรา) มันก็ใช้ได้ดี
h2ooooooo

3
ทุกคนลืมว่าคุณจะสูญเสียประเภทที่ไม่ได้กำหนดไว้ในข้อมูลจำเพาะของ JSON (เช่นวันที่)? คุณจะต้องมี reviver แล้วถ้าคุณใช้วิธีนี้ สิ่งนี้จะดีก็ต่อเมื่อคุณมีประเภทพื้นฐานเช่นตัวเลขสตริงและบูลีน
เดนิส Pshenov

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
โปรดทราบว่าฟังก์ชั่นนี้ไม่สามารถเรียกซ้ำได้ อ้างถึงคำตอบโดยCarlo Fontanosสำหรับการแก้ปัญหาแบบเรียกซ้ำ
Courtney Miles


12

ใช้ฟังก์ชั่นการส่งข้อความในตัวเพียงแค่พิมพ์

$realArray = (array)$stdClass;

1
ฉันชอบสิ่งนี้มากกว่า json_decode / encode, สะอาดกว่า +1 มากขึ้น
Logan

2
วิธีนี้เป็นวิธีที่สะอาดกว่า แต่ก็ยังไม่ซ้ำและทำงานเหมือนกับ get_object_vars () ในขณะที่วิธีการ json_decode / เข้ารหัสมีความรู้สึกของการแฮ็คมันทำงานซ้ำ
Debbie V

3

เพิ่ง googled มันและพบว่าที่นี่เป็นฟังก์ชั่นที่ใช้งานง่ายที่มีประโยชน์สำหรับการแปลงวัตถุ 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

นี่คือรุ่นของคำตอบของ Carlo ที่สามารถใช้ในชั้นเรียน:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.