วิธีการแปลงอาร์เรย์เป็นวัตถุใน PHP?


367

ฉันจะแปลงอาเรย์แบบนี้เป็นวัตถุได้อย่างไร

[128] => Array
    (
        [status] => Figure A.
 Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution.
    )

[129] => Array
    (
        [status] => The other day at work, I had some spare time
    )

4
คุณต้องการได้วัตถุแบบใด สิ่งที่ฉันหมายถึงคือสิ่งที่ควรมีคุณสมบัติ?
Pascal MARTIN

ในวงที่ควรจะเป็นเพราะทั้งสองสถานะคืออาร์เรย์ข้อมูลเดียวเพื่อให้ทั้งสองจะ printet
streetparade

ไม่แน่ใจว่าตั้งแต่เมื่อใด แต่นี่เป็นเพียงการทำงาน:$a = (object)['hello' => 'world'];
Nishchal Gautam

คำตอบ:


588

ในกรณีที่ง่ายที่สุดอาจเพียงพอที่จะ "ส่ง" อาร์เรย์เป็นวัตถุ:

$object = (object) $array;

อีกทางเลือกหนึ่งคือการยกตัวอย่างคลาสมาตรฐานเป็นตัวแปรและวนรอบอาร์เรย์ของคุณในขณะที่กำหนดค่าอีกครั้ง:

$object = new stdClass();
foreach ($array as $key => $value)
{
    $object->$key = $value;
}

ดังที่Edson Medinaชี้ให้เห็นทางออกที่ดีจริงๆคือการใช้json_ฟังก์ชั่นในตัว:

$object = json_decode(json_encode($array), FALSE);

สิ่งนี้ (ซ้ำ) แปลงอาร์เรย์ย่อยทั้งหมดของคุณเป็นวัตถุซึ่งคุณอาจต้องการหรือไม่ต้องการ น่าเสียดายที่มันมีประสิทธิภาพสูงถึง2-3x ในการเข้าใกล้ลูป

คำเตือน! (ขอบคุณ Ultra สำหรับความคิดเห็น):

json_decode บนสภาพแวดล้อมที่แตกต่างกันแปลงข้อมูล UTF-8 ในรูปแบบที่แตกต่างกัน ฉันได้รับค่า '240.00' ในพื้นที่และ '240' เกี่ยวกับการผลิต - ผู้ทำลายที่ยิ่งใหญ่ Morover ถ้าการแปลงล้มเหลวจะได้รับคืนเป็น NULL


41
"เนื่องจากตัวแปรไม่สามารถขึ้นต้นด้วยตัวเลข" ได้พวกเขาสามารถ: $ object -> {3} = 'xyz';
chelmertz

11
"มีผลการดำเนินงาน 2-3x" ซึ่งเป็นการเปรียบเทียบที่ไม่เป็นธรรมเนื่องจากวิธีหลังส่งคืนวัตถุแบบเรียกซ้ำในขณะที่วิธีการวนซ้ำโดยไม่มีเงื่อนไขเพิ่มเติม (เช่นในคำตอบของ @streetparade) จะแปลงระดับแรกเท่านั้น
feeela

8
@feeela ฉันไม่คิดว่ามันไม่ยุติธรรมเลย .. ฉันพูดถึงว่ามันทำให้เกิด Conversion ซ้ำ นอกจากนี้ยังมีการเข้าชมประสิทธิภาพ 2-3 เท่าโดยใช้อาร์เรย์อินพุตแบบแบน (ซึ่งจะไม่ใช้การเรียกซ้ำใด ๆ )
jlb

6
คำเตือน! json_decode บนสภาพแวดล้อมที่แตกต่างกันแปลงข้อมูล UTF-8 ในรูปแบบที่แตกต่างกัน ฉันได้รับค่า '240.00' ในพื้นที่และ '240' เกี่ยวกับการผลิต - ผู้ทำลายที่ยิ่งใหญ่ Morover ถ้าการแปลงล้มเหลวสตริงจะได้รับคืนเป็น NULL
Szymon Toda

1
หมายเหตุเมื่อใช้ฟังก์ชัน json_ *: การอ้างอิง (เช่นไปยังอาร์เรย์อื่น ๆ ) ที่จัดเก็บในอาร์เรย์ดั้งเดิมจะถูกทำซ้ำในกรณีนี้ สมมติว่าคีย์xในอาร์เรย์เก็บการอ้างอิงไปยังอาร์เรย์อื่น จากนั้น$object->xหลังจากดำเนินการหนึ่งซับของคุณจะซ้ำกัน$array['x']ไม่มีการอ้างอิงไปยังอาร์เรย์เดิมอีกต่อไป สิ่งนี้อาจไม่เป็นอันตรายในบางแอพพลิเคชั่น แต่สำหรับอาร์เรย์ขนาดใหญ่มันจะสูญเสียความทรงจำและอาจทำให้การประมวลผลยุ่งเหยิงหากมีการใช้การอ้างอิงในภายหลัง
Coprolal

153

คุณสามารถใช้ชนิดการหล่อเพื่อแปลงอาร์เรย์เป็นวัตถุ

// *convert array to object* Array([id]=> 321313[username]=>shahbaz)
$object = (object) $array_name;

//now it is converted to object and you can access it.
echo $object->username;

107

วิธีง่ายๆก็คือ

$object = (object)$array;

แต่นั่นไม่ใช่สิ่งที่คุณต้องการ หากคุณต้องการวัตถุที่คุณต้องการบรรลุบางสิ่งบางอย่าง แต่มันหายไปในคำถามนี้ การใช้วัตถุเพียงเพื่อเหตุผลในการใช้วัตถุก็ไม่มีเหตุผล


2
ไม่ทำงานฉันทำอย่างนั้นก่อนที่ฉันจะถามคำถามที่นี่ดังนั้นจึงต้องมีวิธีอื่นในการ
ลงมือทำ

20
ทำไมเขาต้องให้เหตุผลว่าทำไมเขาต้องการใช้วัตถุ? ฉันไม่คิดว่ามันเกี่ยวข้องกับวิธีการทำ บางทีเขาอาจต้องการ json_encode พวกเขาหรือทำให้เป็นอันดับ? อาจมีหลายสิบเหตุผลในการทำเช่นนี้
zombat

hmm .. ฉันดูที่ผลลัพธ์ของเบราว์เซอร์ดูเหมือนว่าวัตถุนี้ (stdClass) # 150 (130) {[0] => อาร์เรย์ (1) {["สถานะ"] => สตริง (130) "ที่ Mac เครื่องสุดท้ายและ ผู้ใช้ Linux ไม่ต้องรู้สึกเหมือนเป็นพลเมืองชั้นสองในดินแดน Chrome: พวกเขามีรุ่นเบต้าอย่างเป็นทางการ… "} เป็นทางการซึ่งเป็นวัตถุ แต่จะย้ำสิ่งนี้ได้อย่างไรว่าฉันสามารถมีสถานะเช่น $ obj-> สถานะความคิดใด ๆ ?
streetparade

zombat, JSON encode นั้นไม่มีเหตุผลในการใช้อ็อบเจกต์มีค่าสถานะเป็น json_encode () เพื่อใช้ออบเจ็กต์ ด้วยการทำให้เป็นอันดับหนึ่งจะต้องมีประเภทวัตถุที่คาดหวังโดยผู้รับ และโดยทั่วไปแล้วฉันพยายามช่วยเหลือปัญหาจริง สำหรับฉันคำถามนี้แสดงถึงว่ามีความผิดพลาดทางสถาปัตยกรรมที่อื่น
โยฮันเน

เป็นคนดีทำงานร่วมกับอาร์เรย์ laravel เพื่อคัดค้านปัญหา
Anthony Kal

105

แฮ็คด่วน:

// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);

ไม่สวย แต่ใช้งานได้


2
ฉันชอบวิธีนี้จริง ๆ การใช้ฟังก์ชันในตัวแทนการกำหนดโดยผู้ใช้จะเร็วกว่าเสมอและใช้งานได้ดี ขอบคุณสำหรับทิป.
aknatn

@Oddant วิธีนี้แก้ปัญหาที่กล่าวถึงข้างต้น (แปลงอาร์เรย์เป็นวัตถุ) พูดจาโผงผางของคุณควรถูกนำไปโพสต์หลักไม่ใช่ทางออกของฉัน
Edson Medina

@EdsonMedina ฉันได้โพสต์ของฉันลงไปมากเกินไป
vdegenne

1
@Oddant เป็นธรรมกับ @EdsonMedina คำถามดั้งเดิมไม่ได้ระบุสิ่งที่การมองเห็นคุณลักษณะที่ต้องการและเนื่องจาก OP ไม่ได้ใช้$thisในการแสดงความคิดเห็นที่ตามมาเป็น accessor มันมีนัยมากเขา / เธอต้องการstdClassอินสแตนซ์เป็นเอาท์พุทและไม่ คลาสที่ผู้ใช้กำหนดเช่นคำตอบของคุณใช้ ฉันเห็นด้วยกับความสง่างามของวิธีแก้ปัญหานี้ แต่น่าเสียดายที่มันเป็นรูปแบบที่ใช้กันทั่วไปในการแก้ปัญหานี้ด้วยอาร์เรย์ที่ซ้อนกันซึ่งการส่งไปยังวัตถุจะไม่ทำงาน อาจเป็นไปได้ว่า OP ใช้อินเทอร์เฟซที่ต้องการและคัดค้านเป็นอินพุตและไม่ใช่อาร์เรย์
DeaconDesperado

3
อย่าลืมว่าใช้วิธีนี้คุณจะสูญเสียทั้งหมดยกเว้นประเภทพื้นฐาน DateTime จะเป็นตัวแปลง stdObject
เดนิส Pshenov

97

นี่คือสามวิธี:

  1. ปลอมวัตถุจริง:

    class convert
    {
        public $varible;
    
        public function __construct($array)
        {
            $this = $array;
        }
    
        public static function toObject($array)
        {
            $array = new convert($array);
            return $array;
        }
    }
  2. แปลงอาร์เรย์เป็นวัตถุโดยการแปลงให้เป็นวัตถุ:

    $array = array(
        // ...
    );
    $object = (object) $array;
  3. แปลงอาเรย์ด้วยตนเองเป็นวัตถุ:

    $object = object;
    foreach ($arr as $key => $value) {
        $object->{$key} = $value;
    }

2
ขอบคุณอืม แต่คลาสใบหน้าของคุณให้ข้อผิดพลาดดังต่อไปนี้ข้อผิดพลาดร้ายแรง: ไม่สามารถกำหนด $ this ใหม่ใน /var/www/bot/inc/twitter-bot.php บรรทัดที่ 10
streetparade

1
และ typcasint @ reference ไม่ใช่ความคิดที่ดีแม้มันจะไม่ทำงานที่นี่เป็นสิ่งที่ฉันคาดไม่ถึง T_OBJECT_CAST โดยคาดว่า T_NEW หรือ T_STRING หรือ T_VARIABLE หรือ '$'
streetparade

2
$ array = & (วัตถุ) $ array == การใช้ KISS ที่ดี!
mate64

16
ทำไมทุกคนต้องการใช้วิธีที่แตกต่างจาก 2) มีข้อเสียอะไรบ้าง?
Yogu

7
การพิมพ์อาร์เรย์เป็นวัตถุไม่ทำงานบนอาร์เรย์ที่ซ้อนกัน
minhajul

34

มันเป็นวิธีที่ง่ายวิธีนี้จะสร้างวัตถุสำหรับอาร์เรย์แบบเรียกซ้ำเช่นกัน:

$object = json_decode(json_encode((object) $yourArray), FALSE);

4
ผ่านfalseไปjson_decode()จะกลับอาร์เรย์เชื่อมโยง
สนิม

3
@ user3284463 การส่งผ่านtrueไปยังjson_decodeจะส่งกลับอาร์เรย์ที่เชื่อมโยงfalseเป็นค่าเริ่มต้นและจะส่งคืนStdClassอินสแตนซ์
Elliot Reed

23

ขึ้นอยู่กับตำแหน่งที่คุณต้องการและวิธีการเข้าถึงวัตถุนั้นมีหลายวิธีที่จะทำ

ตัวอย่างเช่นเพียงพิมพ์มัน

$object =  (object) $yourArray;

อย่างไรก็ตามสิ่งที่เข้ากันได้มากที่สุดคือการใช้วิธีการยูทิลิตี้ (ยังไม่ได้เป็นส่วนหนึ่งของ PHP) ที่ดำเนินการคัดเลือก PHP มาตรฐานขึ้นอยู่กับสตริงที่ระบุประเภท (หรือโดยละเว้นมันเพียงแค่อ้างอิงค่า):

/**
 * dereference a value and optionally setting its type
 *
 * @param mixed $mixed
 * @param null  $type (optional)
 *
 * @return mixed $mixed set as $type
 */
function rettype($mixed, $type = NULL) {
    $type === NULL || settype($mixed, $type);
    return $mixed;
}

ตัวอย่างการใช้งานในกรณีของคุณ (การสาธิตออนไลน์ ):

$yourArray = Array('status' => 'Figure A. ...');

echo rettype($yourArray, 'object')->status; // prints "Figure A. ..."

17

อันนี้ใช้ได้สำหรับฉัน

  function array_to_obj($array, &$obj)
  {
    foreach ($array as $key => $value)
    {
      if (is_array($value))
      {
      $obj->$key = new stdClass();
      array_to_obj($value, $obj->$key);
      }
      else
      {
        $obj->$key = $value;
      }
    }
  return $obj;
  }

function arrayToObject($array)
{
 $object= new stdClass();
 return array_to_obj($array,$object);
}

การใช้งาน:

$myobject = arrayToObject($array);
print_r($myobject);

ผลตอบแทน:

    [127] => stdClass Object
        (
            [status] => Have you ever created a really great looking website design
        )

    [128] => stdClass Object
        (
            [status] => Figure A.
 Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution.
        )

    [129] => stdClass Object
        (
            [status] => The other day at work, I had some spare time
        )

เหมือนปกติคุณสามารถวนซ้ำได้เหมือน:

foreach($myobject as $obj)
{
  echo $obj->status;
}

แต่อันนี้ช้ากว่าประมาณ 500% (ทดสอบ) กว่าการคัดเลือกนักแสดง: $ obj = (วัตถุ) $ array;
xZero

@xZero แต่ใช้$obj = (object) $array;ไม่ได้กับอาร์เรย์หลายมิติ
Jeff Puckett

15

ไม่มีวิธีการในตัวที่จะทำเท่าที่ฉันรู้ แต่มันง่ายพอ ๆ กับลูปธรรมดา:

    $obj= new stdClass();

    foreach ($array as $k=> $v) {
        $obj->{$k} = $v;
    }

คุณสามารถอธิบายได้ว่าหากคุณต้องการให้มันสร้างวัตถุของคุณซ้ำ ๆ


14

คุณสามารถใช้ฟังก์ชัน (วัตถุ) เพื่อแปลงอาร์เรย์ของคุณเป็นวัตถุ

$arr= [128=> ['status'=>
                 'Figure A. Facebook \'s horizontal scrollbars showing up on a 1024x768 screen resolution.'],
                  129=>['status'=>'The other day at work, I had some spare time']];

            $ArrToObject=(object)$arr;
            var_dump($ArrToObject);

ผลลัพธ์จะเป็นวัตถุที่มีอาร์เรย์:

object (stdClass) # 1048 (2) {[128] => อาร์เรย์ (1) {

["status"] => string (87) "รูปที่ A. แถบเลื่อนแนวนอนของ Facebook ปรากฏขึ้นที่ความละเอียดหน้าจอ 1024x768" }

[129] => array (1) {["status"] => string (44) "วันอื่น ๆ ที่ทำงานฉันมีเวลาว่าง"}}


9

จริงๆแล้วถ้าคุณต้องการใช้กับอาร์เรย์หลายมิติคุณจะต้องใช้การเรียกซ้ำ

static public function array_to_object(array $array)
{
    foreach($array as $key => $value)
    {
        if(is_array($value))
        {
            $array[$key] = self::array_to_object($value);
        }
    }
    return (object)$array;
}

8

ฉันจะไปด้วยวิธีที่สะอาดเช่นนี้:

<?php

class Person {

  private $name;
  private $age;
  private $sexe;

  function __construct ($payload)
  {
     if (is_array($payload))
          $this->from_array($payload);
  }


  public function from_array($array)
  {
     foreach(get_object_vars($this) as $attrName => $attrValue)
        $this->{$attrName} = $array[$attrName];
  }

  public function say_hi ()
  {
     print "hi my name is {$this->name}";
  }
}

print_r($_POST);
$mike = new Person($_POST);
$mike->say_hi();

?>

หากคุณส่ง:

formulaire

คุณจะได้รับสิ่งนี้:

ไมค์

ฉันพบว่ามีเหตุผลมากกว่านี้เมื่อเปรียบเทียบคำตอบข้างต้นจากวัตถุควรใช้เพื่อวัตถุประสงค์ที่พวกเขาสร้างขึ้นมาเพื่อ (สิ่งห่อหุ้มน่ารักเล็ก ๆ น้อย ๆ ที่น่ารัก)

นอกจากนี้การใช้ get_object_vars ต้องแน่ใจว่าไม่มีการสร้างคุณสมบัติเพิ่มเติมในวัตถุที่มีการจัดการ (คุณไม่ต้องการรถที่มีชื่อสกุลหรือบุคคลที่มีพฤติกรรม 4 ล้อ)


ทำไมคุณไม่ใช้ $ attr_value แทน $ array [$ attr_name]; ในฟังก์ชั่น yourpublic from_array ($ array) ฟังก์ชั่น
Sakkeer Hussain

7

คุณสามารถใช้ ArrayObject ได้เช่น:

<?php
    $arr = array("test",
                 array("one"=>1,"two"=>2,"three"=>3), 
                 array("one"=>1,"two"=>2,"three"=>3)
           );
    $o = new ArrayObject($arr);
    echo $o->offsetGet(2)["two"],"\n";
    foreach ($o as $key=>$val){
        if (is_array($val)) {
            foreach($val as $k => $v) {
               echo $k . ' => ' . $v,"\n";
            }
        }
        else
        {
               echo $val,"\n";
        }
    }
?>

//Output:
  2
  test
  one => 1
  two => 2
  three => 3
  one => 1
  two => 2
  three => 3

1
สำหรับความคิดเห็นของฉันนี้ควรเป็นคำตอบที่ดีที่สุด ข้อมูลเพิ่มเติม herre: php.net/manual/en/arrayobject.construct.php
Julian

7

สิ่งที่ฉันใช้ (เป็นสมาชิกชั้นเรียน):

const MAX_LEVEL = 5; // change it as needed

public function arrayToObject($a, $level=0)
{

    if(!is_array($a)) {
        throw new InvalidArgumentException(sprintf('Type %s cannot be cast, array expected', gettype($a)));
    }

    if($level > self::MAX_LEVEL) {
        throw new OverflowException(sprintf('%s stack overflow: %d exceeds max recursion level', __METHOD__, $level));
    }

    $o = new stdClass();
    foreach($a as $key => $value) {
        if(is_array($value)) { // convert value recursively
            $value = $this->arrayToObject($value, $level+1);
        }
        $o->{$key} = $value;
    }
    return $o;
}

7

เทคนิคซับซ้อนน้อย แต่ง่ายต่อการขยาย:

สมมติว่าคุณมีอาร์เรย์

$a = [
     'name' => 'ankit',
     'age' => '33',
     'dob' => '1984-04-12'
];

สมมติว่าคุณมีคลาส Person ซึ่งอาจมีแอตทริบิวต์มากหรือน้อยจากอาร์เรย์นี้ ตัวอย่างเช่น

class Person 
{
    private $name;
    private $dob;
    private $age;
    private $company;
    private $city;
}

หากคุณยังต้องการเปลี่ยนอาเรย์ของคุณเป็นวัตถุบุคคล คุณสามารถใช้คลาส ArrayIterator

$arrayIterator = new \ArrayIterator($a); // Pass your array in the argument.

ตอนนี้คุณมีวัตถุตัววนซ้ำ

สร้างคลาสที่ขยายคลาส FilterIterator ที่คุณต้องกำหนดวิธีการนามธรรมยอมรับ ทำตามตัวอย่าง

class PersonIterator extends \FilterIterator
{
    public function accept()
    {
        return property_exists('Person', parent::current());
    }
}

impelmentation ข้างต้นจะผูกคุณสมบัติเฉพาะถ้ามันมีอยู่ในชั้นเรียน

เพิ่มวิธีการอีกหนึ่งวิธีในคลาส PersonIterator

public function getObject(Person $object)
{
        foreach ($this as $key => $value)
        {
            $object->{'set' . underscoreToCamelCase($key)}($value);
        }
        return $object;
}

ตรวจสอบให้แน่ใจว่าคุณได้กำหนด mutators ในชั้นเรียนของคุณ ตอนนี้คุณพร้อมที่จะเรียกใช้ฟังก์ชันเหล่านี้ในตำแหน่งที่คุณต้องการสร้างวัตถุ

$arrayiterator = new \ArrayIterator($a);
$personIterator = new \PersonIterator($arrayiterator);

$personIterator->getObject(); // this will return your Person Object. 

6

การสอบถามซ้ำคือเพื่อนของคุณ:

function __toObject(Array $arr) {
    $obj = new stdClass();
    foreach($arr as $key=>$val) {
        if (is_array($val)) {
            $val = __toObject($val);
        }
        $obj->$key = $val;
    }

    return $obj;
}

6

สิ่งนี้ต้องการ PHP7 เพราะฉันเลือกใช้ฟังก์ชั่นแลมบ์ดาเพื่อล็อค 'Innerfunc' ภายในฟังก์ชั่นหลัก ฟังก์ชั่นแลมบ์ดาถูกเรียกซ้ำ, ดังนั้นความต้องการ: "use (& $ innerfunc)" คุณสามารถทำได้ใน PHP5 แต่ไม่สามารถซ่อน innerfunc

function convertArray2Object($defs) {
    $innerfunc = function ($a) use ( &$innerfunc ) {
       return (is_array($a)) ? (object) array_map($innerfunc, $a) : $a; 
    };
    return (object) array_map($innerfunc, $defs);
}

5

ใช้ฟังก์ชั่นนี้ที่ฉันได้ทำ:

function buildObject($class,$data){
    $object = new $class;
    foreach($data as $key=>$value){
        if(property_exists($class,$key)){
            $object->{'set'.ucfirst($key)}($value);
        }
    }
    return $object;
}

การใช้งาน:

$myObject = buildObject('MyClassName',$myArray);

5

หนึ่งในสายการบิน

$object= json_decode(json_encode($result_array, JSON_FORCE_OBJECT));

1
โปรดทราบว่าการอ้างอิง (เช่นไปยังอาร์เรย์อื่น ๆ ) ที่จัดเก็บไว้ในอาร์เรย์เดิมจะถูกทำซ้ำโดยหนึ่งซับ สมมติว่าคีย์xในอาร์เรย์เก็บการอ้างอิงไปยังอาร์เรย์อื่น จากนั้น$object->xหลังจากที่ดำเนินการหนึ่งซับของคุณจะซ้ำกัน$result_array['x']ไม่ใช่อาร์เรย์ที่เหมือนกัน
Coprolal

4

ง่าย:

$object = json_decode(json_encode($array));

ตัวอย่าง:

$array = array(
    'key' => array(
        'k' => 'value',
    ),
    'group' => array('a', 'b', 'c')
);

$object = json_decode(json_encode($array));

จากนั้นต่อไปนี้เป็นจริง:

$object->key->k === 'value';
$object->group === array('a', 'b', 'c')

1
ฉันคิดว่านี่เป็นวิธีแก้ปัญหา ทำไมต้องเข้ารหัสอาร์เรย์เป็น json แล้วถอดรหัสมัน? มันไม่ใช่การตัดสินใจที่ดีที่สุดสำหรับฉัน
Julian

1
@Julian เพราะมันทำงานแบบวนซ้ำทำในลักษณะที่กำหนดไว้อย่างถูกต้องและเชื่อถือได้เพียงพอ ("มาตรฐาน") และยังเร็วพอที่จะเป็นทางเลือกที่ดีในการใช้เวทมนตร์ลิงแบบสุ่มด้วยมือ
Sz.

3

คุณสามารถทำได้โดยการเพิ่ม(วัตถุ)ทางด้านซ้ายของตัวแปรเพื่อสร้างวัตถุใหม่

<?php
$a = Array
    ( 'status' => " text" );
var_dump($a);
$b = (object)$a;
var_dump($b);
var_dump($b->status);

http://codepad.org/9YmD1KsU


1
อาจคุ้มค่าที่จะกล่าวถึงสิ่งนี้เรียกว่า "การคัดเลือกนักแสดง" หรือ "การคัดเลือกนักแสดง": php.net/manual/en/…และพฤติกรรมของ (วัตถุ) อาร์เรย์ () มีการบันทึกไว้ที่นี่: php.net/manual/en/ …
Pete

2

การใช้json_encodeเป็นปัญหาเนื่องจากวิธีการจัดการข้อมูลที่ไม่ใช่ UTF-8 เป็นที่น่าสังเกตว่าjson_encode/ json_encodeวิธียังออกจากอาร์เรย์ที่ไม่ใช่ความสัมพันธ์เป็นอาร์เรย์ นี่อาจเป็นหรือไม่ใช่สิ่งที่คุณต้องการ เมื่อเร็ว ๆ นี้ฉันอยู่ในตำแหน่งที่ต้องการสร้างฟังก์ชันการทำงานของโซลูชันนี้ใหม่ แต่ไม่ต้องใช้json_ฟังก์ชั่น นี่คือสิ่งที่ฉันมาด้วย:

/**
 * Returns true if the array has only integer keys
 */
function isArrayAssociative(array $array) {
    return (bool)count(array_filter(array_keys($array), 'is_string'));
}

/**
 * Converts an array to an object, but leaves non-associative arrays as arrays. 
 * This is the same logic that `json_decode(json_encode($arr), false)` uses.
 */
function arrayToObject(array $array, $maxDepth = 10) {
    if($maxDepth == 0) {
        return $array;
    }

    if(isArrayAssociative($array)) {
        $newObject = new \stdClass;
        foreach ($array as $key => $value) {
            if(is_array($value)) {
                $newObject->{$key} = arrayToObject($value, $maxDepth - 1);
            } else {
                $newObject->{$key} = $value;
            }
        }
        return $newObject;
    } else {

        $newArray = array();
        foreach ($array as $value) {
            if(is_array($value)) {
                $newArray[] = arrayToObject($value, $maxDepth - 1);
            } else {
                $newArray[] = $value;
            }                
        }
        return $newArray;
    }
}

2

วิธีที่ดีที่สุดในโลก :)

function arrayToObject($conArray)
{
    if(is_array($conArray)){
        /*
        * Return array converted to object
        * Using __FUNCTION__ (Magic constant)
        * for recursive call
        */
        return (object) array_map(__FUNCTION__, $conArray);
    }else{
        // Return object
        return $conArray;
    }
}

ถ้าคุณใช้วิธีการต่าง ๆ คุณจะมีปัญหา นี่เป็นวิธีที่ดีที่สุด คุณเคยเห็น


2

อาร์เรย์หลายมิติเป็นวัตถุ รหัสนี้ใช้สำหรับการแปลงวิธีการค้นหา API แบบลองและจับของ Bing

try {
        // Perform the Web request and get the JSON response
        $context = stream_context_create($options);
        $results = file_get_contents($url . "?cc=" . $country . "&category=" . $type, false, $context);
        $results = json_decode($results);
        return response()->json($results);
    } catch (\Exception $e) {
        $results = array('value' => array(
                (object) array(
                    "name" => "Unable to Retrive News",
                    "url" => "http://www.sample.com/",
                    "image" => (object) array("thumbnail" => (object) array("contentUrl" => "")),
                    "publishedAt" => "",
                    "description" => "")
            )
        );
        $results = (object) $results;
        return response()->json($results);
    }

2

คุณสามารถใช้ Reflection:

<?php

$array = ['name'=>'maria','age'=>33];

class Person {

    public $name;
    public $age;

    public function __construct(string $name, string $age){
        $this->name  = $name;
        $this->age = $age;
    }
}

function arrayToObject(array $array, string $class_name){

    $r = new ReflectionClass($class_name);
    $object = $r->newInstanceWithoutConstructor();
    $list = $r->getProperties();
    foreach($list as $prop){
      $prop->setAccessible(true);
      if(isset($array[$prop->name]))
        $prop->setValue($object, $array[$prop->name]);
    } 

    return $object;

}

$pessoa1 = arrayToObject($array, 'Person');
var_dump($pessoa1);

1

CakePHP มี Set :: recursive class: map class ที่แมปอาเรย์เป็นวัตถุ คุณอาจต้องเปลี่ยนสิ่งที่มีลักษณะเป็นอาร์เรย์เพื่อให้วัตถุมีลักษณะตามที่คุณต้องการ

http://api.cakephp.org/view_source/set/#line-158

กรณีที่เลวร้ายที่สุดคุณอาจได้รับแนวคิดเล็กน้อยจากฟังก์ชั่นนี้


1

เห็นได้ชัดว่าเป็นเพียงการคาดการณ์ของคำตอบของคนอื่น ๆ แต่นี่คือฟังก์ชั่นวนซ้ำที่จะแปลงอาร์เรย์ของวัสดุคลุมด้วยหญ้าเป็นวัตถุ:

   function convert_array_to_object($array){
      $obj= new stdClass();
      foreach ($array as $k=> $v) {
         if (is_array($v)){
            $v = convert_array_to_object($v);   
         }
         $obj->{strtolower($k)} = $v;
      }
      return $obj;
   }

และจำไว้ว่าถ้าอาร์เรย์มีแผงปุ่มกดตัวเลขที่พวกเขายังคงสามารถอ้างอิงในวัตถุที่เกิดขึ้นโดยใช้{}(เช่น: $obj->prop->{4}->prop)


1

โดยได้รับแรงบันดาลใจจากรหัสเหล่านี้ฉันพยายามสร้างรุ่นที่ได้รับการปรับปรุงพร้อมการสนับสนุน: ชื่อคลาสเฉพาะหลีกเลี่ยงวิธีการสร้างรูปแบบ 'beans' และโหมดเข้มงวด (ตั้งค่าคุณสมบัติที่มีอยู่เท่านั้น):

    class Util {

static function arrayToObject($array, $class = 'stdClass', $strict = false) {
        if (!is_array($array)) {
            return $array;
        }

        //create an instance of an class without calling class's constructor
        $object = unserialize(
                sprintf(
                        'O:%d:"%s":0:{}', strlen($class), $class
                )
        );

        if (is_array($array) && count($array) > 0) {
            foreach ($array as $name => $value) {
                $name = strtolower(trim($name));
                if (!empty($name)) {

                    if(method_exists($object, 'set'.$name)){
                        $object->{'set'.$name}(Util::arrayToObject($value));
                    }else{
                        if(($strict)){

                            if(property_exists($class, $name)){

                                $object->$name = Util::arrayToObject($value); 

                            }

                        }else{
                            $object->$name = Util::arrayToObject($value); 
                        }

                    }

                }
            }
            return $object;
        } else {
            return FALSE;
        }
        }
}

1

รหัส

json_decode(json_encode($arr), false)ฟังก์ชั่นงานนี้เป็นเช่นเดียวกับ

function arrayToObject(array $arr)
{
    $flat = array_keys($arr) === range(0, count($arr) - 1);
    $out = $flat ? [] : new \stdClass();

    foreach ($arr as $key => $value) {
        $temp = is_array($value) ? $this->arrayToObject($value) : $value;

        if ($flat) {
            $out[] = $temp;
        } else {
            $out->{$key} = $temp;
        }
    }

    return $out;
}

การทดสอบ

ทดสอบ 1: อาร์เรย์แบบแบน

$arr = ["a", "b", "c"];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));

เอาท์พุท:

array(
    0 => 'a',
    1 => 'b',
    2 => 'c',
)
array(
    0 => 'a',
    1 => 'b',
    2 => 'c',
)

ทดสอบ 2: อาร์เรย์ของวัตถุ

$arr = [["a" => 1], ["a" => 1], ["a" => 1]];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));

เอาท์พุท:

array(
    0 => stdClass::__set_state(array('a' => 1,)),
    1 => stdClass::__set_state(array('a' => 1,)),
    2 => stdClass::__set_state(array('a' => 1,)),
)
array(
    0 => stdClass::__set_state(array('a' => 1,)),
    1 => stdClass::__set_state(array('a' => 1,)),
    2 => stdClass::__set_state(array('a' => 1,)),
)

ทดสอบ 3: วัตถุ

$arr = ["a" => 1];
var_export(json_decode($arr));
var_export($this->arrayToObject($arr));

เอาท์พุท:

stdClass::__set_state(array('a' => 1,))
stdClass::__set_state(array('a' => 1,))

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