Pertanyaan PHP - Array rekursif ke Object?


Apakah ada cara untuk mengubah multidimensi array ke a stdClass objek dalam PHP?

Casting sebagai (object) tampaknya tidak bekerja secara rekursif. json_decode(json_encode($array)) menghasilkan hasil yang saya cari, tetapi harus ada cara yang lebih baik ...


30
2018-01-25 05:55


asal


Jawaban:


Sejauh yang saya tahu, tidak ada solusi prebuilt untuk ini, jadi Anda bisa menggulirnya sendiri:

function array_to_object($array) {
  $obj = new stdClass;
  foreach($array as $k => $v) {
     if(strlen($k)) {
        if(is_array($v)) {
           $obj->{$k} = array_to_object($v); //RECURSION
        } else {
           $obj->{$k} = $v;
        }
     }
  }
  return $obj;
} 

51
2018-01-25 06:03



Saya tahu jawaban ini datang terlambat tetapi saya akan mempostingnya untuk siapa saja yang mencari solusi.

Alih-alih semua looping ini dll, Anda dapat menggunakan fungsi json_ * PHP asli. Saya punya beberapa fungsi berguna yang saya gunakan banyak

/**
 * Convert an array into a stdClass()
 * 
 * @param   array   $array  The array we want to convert
 * 
 * @return  object
 */
function arrayToObject($array)
{
    // First we convert the array to a json string
    $json = json_encode($array);

    // The we convert the json string to a stdClass()
    $object = json_decode($json);

    return $object;
}


/**
 * Convert a object to an array
 * 
 * @param   object  $object The object we want to convert
 * 
 * @return  array
 */
function objectToArray($object)
{
    // First we convert the object into a json string
    $json = json_encode($object);

    // Then we convert the json string to an array
    $array = json_decode($json, true);

    return $array;
}

Semoga ini bisa membantu


32
2018-02-07 22:59



function toObject($array) {
    $obj = new stdClass();
    foreach ($array as $key => $val) {
        $obj->$key = is_array($val) ? toObject($val) : $val;
    }
    return $obj;
}

7
2017-08-02 08:18



/**
 * Recursively converts associative arrays to stdClass while keeping integer keys subarrays as arrays
 * (lists of scalar values or collection of objects).
 */
function a2o( array $array ) {
    $resultObj = new \stdClass;
    $resultArr = array();
    $hasIntKeys = false;
    $hasStrKeys = false;
    foreach ( $array as $k => $v ) {
        if ( !$hasIntKeys ) {
            $hasIntKeys = is_int( $k );
        }
        if ( !$hasStrKeys ) {
            $hasStrKeys = is_string( $k );
        }
        if ( $hasIntKeys && $hasStrKeys ) {
            $e = new \Exception( 'Current level has both integer and string keys, thus it is impossible to keep array or convert to object' );
            $e->vars = array( 'level' => $array );
            throw $e;
        }
        if ( $hasStrKeys ) {
            $resultObj->{$k} = is_array( $v ) ? a2o( $v ) : $v;
        } else {
            $resultArr[$k] = is_array( $v ) ? a2o( $v ) : $v;
        }
    }
    return ($hasStrKeys) ? $resultObj : $resultArr;
} 

3
2018-02-08 19:23



Beberapa solusi lain yang diposting di sini gagal untuk membedakan susunan berurutan (apa yang akan terjadi) [] di JS) dari peta ({} di JS.) Untuk banyak kasus penggunaan penting untuk membedakan array PHP yang memiliki semua kunci numerik berurutan, yang harus dibiarkan seperti itu, dari array PHP yang tidak memiliki kunci numerik, yang harus dikonversi ke objek. (Solusi saya di bawah ini tidak terdefinisi untuk array yang tidak termasuk dalam dua kategori di atas.)

Itu json_decode(json_encode($x)) metode menangani dua jenis dengan benar, tetapi bukan solusi tercepat. Ini masih layak, total 25μs per dijalankan pada data sampel saya (rata-rata lebih dari 1M berjalan, dikurangi loop overhead).

Saya membandingkan beberapa variasi dari konverter rekursif dan berakhir dengan yang berikut ini. Ini membangun kembali semua array dan objek (melakukan salinan yang mendalam) tetapi tampaknya lebih cepat daripada solusi alternatif yang memodifikasi array di tempat. Ini jam di 11μs per eksekusi pada data sampel saya:

function array_to_object($x) {
    if (!is_array($x)) {
        return $x;
    } elseif (is_numeric(key($x))) {
        return array_map(__FUNCTION__, $x);
    } else {
        return (object) array_map(__FUNCTION__, $x);
    }
}

Ini adalah versi di tempat. Ini mungkin lebih cepat pada beberapa data input besar di mana hanya sebagian kecil yang perlu diubah, tetapi pada data sampel saya yang diperlukan 15μs per eksekusi:

function array_to_object_inplace(&$x) {
    if (!is_array($x)) {
        return;
    }
    array_walk($x, __FUNCTION__);
    reset($x);
    if (!is_numeric(key($x))) {
        $x = (object) $x;
    }
}

Saya tidak mencoba menggunakan solusi array_walk_recursive()


2
2017-11-14 13:47



Anda dapat menggunakan array_map secara rekursif:

public static function _arrayToObject($array) {
    return is_array($array) ? (object) array_map([__CLASS__, __METHOD__], $array) : $array;
}

Bekerja sempurna untuk saya karena tidak mentransmisikan misalnya objek Karbon ke stdClass dasar (yang dikodekan / decode json tidak)


2
2017-11-11 16:28



public static function _arrayToObject($array) {
    $json = json_encode($array);
    $object = json_decode($json);
    return $object
}

1
2018-01-24 07:36



Cara paling sederhana untuk mengonversi array asosiatif ke objek adalah:

Pertama encode di json, lalu dekode itu.

seperti $objectArray = json_decode(json_encode($associtiveArray));


1
2018-06-29 06:03