Konversi objek PHP ke array asosiatif


760

Saya mengintegrasikan API ke situs web saya yang berfungsi dengan data yang disimpan dalam objek saat kode saya ditulis menggunakan array.

Saya ingin fungsi cepat dan kotor untuk mengonversi objek ke array.

Jawaban:


1392

Cukup ketik saja

$array = (array) $yourObject;

Dari Array :

Jika suatu objek dikonversi ke array, hasilnya adalah array yang elemen-elemennya adalah properti objek. Kunci adalah nama variabel anggota, dengan beberapa pengecualian: properti integer tidak dapat diakses; variabel pribadi memiliki nama kelas yang diawali dengan nama variabel; variabel yang dilindungi memiliki '*' yang diawali dengan nama variabel. Nilai-nilai yang diawali ini memiliki byte nol di kedua sisi.

Contoh: Objek Sederhana

$object = new StdClass;
$object->foo = 1;
$object->bar = 2;

var_dump( (array) $object );

Keluaran:

array(2) {
  'foo' => int(1)
  'bar' => int(2)
}

Contoh: Objek Kompleks

class Foo
{
    private $foo;
    protected $bar;
    public $baz;

    public function __construct()
    {
        $this->foo = 1;
        $this->bar = 2;
        $this->baz = new StdClass;
    }
}

var_dump( (array) new Foo );

Output (dengan diedit untuk kejelasan):

array(3) {
  '\0Foo\0foo' => int(1)
  '\0*\0bar' => int(2)
  'baz' => class stdClass#2 (0) {}
}

Output dengan var_exportbukannya var_dump:

array (
  '' . "\0" . 'Foo' . "\0" . 'foo' => 1,
  '' . "\0" . '*' . "\0" . 'bar' => 2,
  'baz' =>
  stdClass::__set_state(array(
  )),
)

Mengetikkan dengan cara ini tidak akan melakukan pengecoran yang dalam dari objek grafik dan Anda perlu menerapkan byte nol (seperti yang dijelaskan dalam kutipan manual) untuk mengakses atribut non-publik. Jadi ini bekerja paling baik ketika casting objek StdClass atau objek dengan hanya properti publik Untuk cepat dan kotor (apa yang Anda minta) tidak apa-apa.

Lihat juga posting blog yang mendalam ini:


3
Juga pertimbangkan ArrayAccessantarmuka, mungkin dalam kombinasi dengan solusi ini. php.net/manual/en/class.arrayaccess.php
alttag

3
Jika Anda memiliki kunci integer yang akan dikonversi menjadi string dan ini dapat menyebabkan masalah besar. Misalnya [1 => "one"]menjadi["1" => "one"]
Oleg

2
@Howie Mengetikkan (array)dan (object)bekerja dengan andal dan sama di semua versi sejak PHP 4.3. Lihat 3v4l.org/X6lhm . Jika Anda mendapatkan kesalahan sintaks, Anda melakukan kesalahan.
Gordon

2
@Howie lihat bagian Changelog untukempty . Anda tidak dapat menggunakan ekspresi dengan emptysebelum 5,5. Ini sama sekali tidak terkait dengan typecasting;)
Gordon

4
Typecast. Iya. Ketik Freakin CAST! Baik. +1
Kaushik Makwana

346

Anda dapat dengan cepat mengonversi objek yang sangat bersarang ke array asosiatif dengan mengandalkan perilaku fungsi penyandian / dekode JSON:

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

12
Ini adalah solusi terbaik jika Anda ingin konversi rekursif mendalam penuh (dan tentu saja tidak keberatan dengan kinerja buruk)
Julian Habekost

2
ini benar-benar membantu saya dengan situasi saya, terima kasih banyak.
Cesar Bielich

9
Dengan hormat, saya pikir itu masih berfungsi ... jangan lupa untuk mengatur parameter ke-2 menjadi true.
Kirk B

3
Parameter kedua memecahkan masalah, bekerja untuk PHP 5.6.25. Terima kasih!
Ju Oliveira

3
Berfungsi sempurna untuk objek bersarang! Terima kasih!
Melody

68

Dari hit Google pertama untuk " objek PHP ke array assoc " kita punya ini:

function object_to_array($data)
{
    if (is_array($data) || is_object($data))
    {
        $result = array();
        foreach ($data as $key => $value)
        {
            $result[$key] = object_to_array($value);
        }
        return $result;
    }
    return $data;
}

Sumbernya ada di codesnippets.joyent.com .


16
Secara pribadi, saya tidak suka ide mengingat fungsi untuk setiap nilai. Saya memiliki versi yang serupa, tetapi dalam 3 baris: function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }Ini hanya mengatur apa pun yang bukan objek atau array dan melanjutkan tanpa penarikan berulang-ulang ke metode kecuali diperlukan.
SpYk3HH

13
@ SpYk3HH: tulis jawaban Anda sendiri?
DanMan

2
Hit pertama untuk "php object to assoc array" adalah stackoverflow.com/questions/4345554/…
Chris

Ini (dan versi dari @ SpYk3HH) tampaknya berkinerja lebih lambat untuk saya daripada opsi json_encode ( stackoverflow.com/a/16111687/470749 ). Saya tidak tahu mengapa pendekatan ini lebih disukai.
Ryan

1
@Ryan json encode dan decode tidak akan bekerja dengan nilai NaN dan INFINITE untuk float dan berpotensi memiliki masalah lain yang tidak dapat saya pikirkan dari atas kepala saya, tetapi untuk banyak kasus ini mungkin pilihan yang lebih baik. Adapun optimasi, apa yang dibutuhkan adalah konteks - izinkan saya pasang posting yang saya tulis tentang subjek ini ternyatacube.com/blog/game-optimization/when-to-optimize . Jadi, jangan mengoptimalkan hal-hal yang tidak memakan banyak waktu karena manfaatnya tidak berarti dalam konteks keseluruhan aplikasi.
Maurycy

61

Jika properti objek Anda bersifat publik, Anda dapat melakukannya:

$array =  (array) $object;

Jika mereka pribadi atau dilindungi, mereka akan memiliki nama kunci yang aneh pada array. Jadi, dalam hal ini Anda akan membutuhkan fungsi berikut:

function dismount($object) {
    $reflectionClass = new ReflectionClass(get_class($object));
    $array = array();
    foreach ($reflectionClass->getProperties() as $property) {
        $property->setAccessible(true);
        $array[$property->getName()] = $property->getValue($object);
        $property->setAccessible(false);
    }
    return $array;
}

Jika properti Anda dilindungi, apakah setAccessible (false) akan mengubahnya kembali ke visibilitas yang dilindungi? atau apakah itu akan menjadikannya pribadi?
Nick Mitchell

Satu-satunya solusi yang saya temukan, yang bekerja dengan properti yang dilindungi. Terima kasih
dav

3
solusi terbaik untuk variabel pribadi dan dilindungi !!
HIRA THAKUR

Di sini baris $ property-> setAccessible (false); akan dieksekusi di setiap properti - bahkan jika itu publik ...
Francois Bourgeois

Luar biasa ... Luar biasa ... Luar biasa. Terima kasih.
Farid Abbas

14
class Test{
    const A = 1;
    public $b = 'two';
    private $c = test::A;

    public function __toArray(){
        return call_user_func('get_object_vars', $this);
    }
}

$my_test = new Test();
var_dump((array)$my_test);
var_dump($my_test->__toArray());

Keluaran

array(2) {
    ["b"]=>
    string(3) "two"
    ["Testc"]=>
    int(1)
}
array(1) {
    ["b"]=>
    string(3) "two"
}

1
Pro dan kontra dari solusi ini? Bagaimana dengan kelas yang dinyatakan sebagai Uji kelas {const A = 1; public $ parent = Test baru (); }
Matteo Gaggiano

13

Ini beberapa kode:

function object_to_array($data) {
    if ((! is_array($data)) and (! is_object($data)))
        return 'xxx'; // $data;

    $result = array();

    $data = (array) $data;
    foreach ($data as $key => $value) {
        if (is_object($value))
            $value = (array) $value;
        if (is_array($value))
            $result[$key] = object_to_array($value);
        else
            $result[$key] = $value;
    }
    return $result;
}

berfungsi paling baik untuk saya (tapi saya perlu menghapus 'xxx' dan mengembalikan $ data)
Gerfried

12

Semua jawaban lain yang diposting di sini hanya berfungsi dengan atribut publik. Berikut adalah salah satu solusi yang berfungsi dengan objek mirip JavaBeans menggunakan refleksi dan getter:

function entity2array($entity, $recursionDepth = 2) {
    $result = array();
    $class = new ReflectionClass(get_class($entity));
    foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
        $methodName = $method->name;
        if (strpos($methodName, "get") === 0 && strlen($methodName) > 3) {
            $propertyName = lcfirst(substr($methodName, 3));
            $value = $method->invoke($entity);

            if (is_object($value)) {
                if ($recursionDepth > 0) {
                    $result[$propertyName] = $this->entity2array($value, $recursionDepth - 1);
                }
                else {
                    $result[$propertyName] = "***";  // Stop recursion
                }
            }
            else {
                $result[$propertyName] = $value;
            }
        }
    }
    return $result;
}

Ya, tapi ... jika Anda menggunakan Object / Array sebagai variabel, yang juga menyebabkan semua ini, mengapa Anda perlu sesuatu selain publicproperti?
SpYk3HH

@ SpYk3HH: Saya tidak mengajukan pertanyaan. Saya bahkan tidak tahu mengapa ada orang yang lebih memilih array daripada objek.
Francois Bourgeois

Eh, saya sering lebih suka mengonversi hasil kueri ke array hanya untuk memberikan "daftar" seragam untuk perulangan, karena sebagian besar hal lain dalam aplikasi yang harus "dilingkarkan" cenderung menjadi array. Hanya membuatnya mudah untuk menulis "metode loop universal". Seringkali, jika saya menggunakan sebuah objek, saya tidak mengulang-ulang properti itu, saya menggunakannya sebagai objek dan menggunakan properti itu sesuai kebutuhan.
SpYk3HH

11

Bagaimana dengan get_object_vars($obj)? Tampaknya berguna jika Anda hanya ingin mengakses properti publik dari suatu objek.

Lihat get_object_vars .


10

Ketik melemparkan objek Anda ke array.

$arr =  (array) $Obj;

Itu akan menyelesaikan masalah Anda.


5
Tidak, tidak akan, jika Anda memiliki properti pribadi atau dilindungi.
forsberg

2
Solusi paling sederhana. Terima kasih
ASD

6

Pertama-tama, jika Anda membutuhkan array dari suatu objek, Anda mungkin harus menyusun data sebagai array terlebih dahulu. Pikirkan tentang itu.

Jangan gunakan a foreach pernyataan atau transformasi JSON. Jika Anda merencanakan ini, sekali lagi Anda bekerja dengan struktur data, bukan dengan objek.

Jika Anda benar-benar membutuhkannya gunakan pendekatan berorientasi objek untuk memiliki kode yang bersih dan dapat dipelihara. Sebagai contoh:

Objek sebagai array

class PersonArray implements \ArrayAccess, \IteratorAggregate
{
    public function __construct(Person $person) {
        $this->person = $person;
    }
    // ...
 }

Jika Anda membutuhkan semua properti, gunakan objek transfer:

class PersonTransferObject
{
    private $person;

    public function __construct(Person $person) {
        $this->person = $person;
    }

    public function toArray() {
        return [
            // 'name' => $this->person->getName();
        ];
    }

 }

6

Anda dapat dengan mudah menggunakan fungsi ini untuk mendapatkan hasilnya:

function objetToArray($adminBar){
    $reflector = new ReflectionObject($adminBar);
    $nodes = $reflector->getProperties();
    $out = [];
    foreach ($nodes as $node) {
        $nod = $reflector->getProperty($node->getName());
        $nod->setAccessible(true);
        $out[$node->getName()] = $nod->getValue($adminBar);
    }
    return $out;
}

Gunakan PHP 5 atau lebih baru.


5

Inilah fungsi PHP rekursif saya untuk mengonversi objek PHP ke array asosiatif:

// ---------------------------------------------------------
// ----- object_to_array_recursive --- function (PHP) ------
// ---------------------------------------------------------
// --- arg1: -- $object  =  PHP Object         - required --
// --- arg2: -- $assoc   =  TRUE or FALSE      - optional --
// --- arg3: -- $empty   =  '' (Empty String)  - optional --
// ---------------------------------------------------------
// ----- Return: Array from Object --- (associative) -------
// ---------------------------------------------------------

function object_to_array_recursive($object, $assoc=TRUE, $empty='')
{
    $res_arr = array();

    if (!empty($object)) {

        $arrObj = is_object($object) ? get_object_vars($object) : $object;

        $i=0;
        foreach ($arrObj as $key => $val) {
            $akey = ($assoc !== FALSE) ? $key : $i;
            if (is_array($val) || is_object($val)) {
                $res_arr[$akey] = (empty($val)) ? $empty : object_to_array_recursive($val);
            }
            else {
                $res_arr[$akey] = (empty($val)) ? $empty : (string)$val;
            }
            $i++;
        }
    }
    return $res_arr;
}

// ---------------------------------------------------------
// ---------------------------------------------------------

Contoh penggunaan:

// ---- Return associative array from object, ... use:
$new_arr1 = object_to_array_recursive($my_object);
// -- or --
// $new_arr1 = object_to_array_recursive($my_object, TRUE);
// -- or --
// $new_arr1 = object_to_array_recursive($my_object, 1);


// ---- Return numeric array from object, ... use:
$new_arr2 = object_to_array_recursive($my_object, FALSE);

3
.. atau oneliner:$new_arr1 = (array) $my_object;
FooBar

1
Versi oneliner dangkal, jadi tidak setara.
Jonathan Lidbeck

5

Untuk mengonversi objek menjadi array, cukup masukkan secara eksplisit:

$name_of_array = (array) $name_of_object;

5

Anda juga dapat membuat fungsi dalam PHP untuk mengonversi objek array:

function object_to_array($object) {
    return (array) $object;
}

@ Akintunde-Rotimi, saya telah membuat fungsi umum dan menunjukkan.
Rakhi Prajapati

4

Anda mungkin ingin melakukan ini ketika Anda memperoleh data sebagai objek dari database:

// Suppose 'result' is the end product from some query $query

$result = $mysqli->query($query);
$result = db_result_to_array($result);

function db_result_to_array($result)
{
    $res_array = array();

    for ($count=0; $row = $result->fetch_assoc(); $count++)
        $res_array[$count] = $row;

    return $res_array;
}

2
Ada jawaban yang diterima dengan 41 upvotes, bukan 1 atau 10, 41. Apa jawaban Anda menambahkannya?
Yaroslav

4

Fungsi kustom untuk mengonversi stdClass ke array:

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

Fungsi kustom lain untuk mengonversi Array ke stdClass:

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

Contoh Penggunaan:

// Create new stdClass Object
$init = new stdClass;

// Add some test data
$init->foo = "Test data";
$init->bar = new stdClass;
$init->bar->baaz = "Testing";
$init->bar->fooz = new stdClass;
$init->bar->fooz->baz = "Testing again";
$init->foox = "Just test";

// Convert array to object and then object back to array
$array = objectToArray($init);
$object = arrayToObject($array);

// Print objects and array
print_r($init);
echo "\n";
print_r($array);
echo "\n";
print_r($object);

4

Menggunakan:

function readObject($object) {
    $name = get_class ($object);
    $name = str_replace('\\', "\\\\", $name); \\ Outcomment this line, if you don't use
                                              \\ class namespaces approach in your project
    $raw = (array)$object;

    $attributes = array();
    foreach ($raw as $attr => $val) {
        $attributes[preg_replace('('.$name.'|\*|)', '', $attr)] = $val;
    }
    return $attributes;
}

Ini mengembalikan array tanpa karakter khusus dan nama kelas.


4

Jawaban ini hanya penyatuan jawaban yang berbeda dari posting ini, tapi itu solusi untuk mengubah objek PHP dengan properti publik atau pribadi dengan nilai sederhana atau array ke array asosiatif ...

function object_to_array($obj)
{
    if (is_object($obj))
        $obj = (array)$this->dismount($obj);
    if (is_array($obj)) {
        $new = array();
        foreach ($obj as $key => $val) {
            $new[$key] = $this->object_to_array($val);
        }
    }
    else
        $new = $obj;
    return $new;
}

function dismount($object)
{
    $reflectionClass = new \ReflectionClass(get_class($object));
    $array = array();
    foreach ($reflectionClass->getProperties() as $property) {
        $property->setAccessible(true);
        $array[$property->getName()] = $property->getValue($object);
        $property->setAccessible(false);
    }
    return $array;
}

3

Beberapa perbaikan pada kode "well-knwon"

/*** mixed Obj2Array(mixed Obj)***************************************/ 
static public function Obj2Array($_Obj) {
    if (is_object($_Obj))
        $_Obj = get_object_vars($_Obj);
    return(is_array($_Obj) ? array_map(__METHOD__, $_Obj) : $_Obj);   
} // BW_Conv::Obj2Array

Perhatikan bahwa jika fungsinya anggota kelas (seperti di atas) Anda harus berubah __FUNCTION__menjadi__METHOD__


3

Anda juga dapat menggunakan Komponen Symfony Serializer

use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
$array = json_decode($serializer->serialize($object, 'json'), true);

3

Untuk kasus Anda itu benar / indah jika Anda akan menggunakan pola "dekorator" atau "transformasi model tanggal". Sebagai contoh:

Model Anda

class Car {
    /** @var int */
    private $color;

    /** @var string */
    private $model;

    /** @var string */
    private $type;

    /**
     * @return int
     */
    public function getColor(): int
    {
        return $this->color;
    }

    /**
     * @param int $color
     * @return Car
     */
    public function setColor(int $color): Car
    {
        $this->color = $color;
        return $this;
    }

    /**
     * @return string
     */
    public function getModel(): string
    {
        return $this->model;
    }

    /**
     * @param string $model
     * @return Car
     */
    public function setModel(string $model): Car
    {
        $this->model = $model;

        return $this;
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return $this->type;
    }

    /**
     * @param string $type
     * @return Car
     */
    public function setType(string $type): Car
    {
        $this->type = $type;

        return $this;
    }
}

Penghias

class CarArrayDecorator
{
    /** @var Car */
    private $car;

    /**
     * CarArrayDecorator constructor.
     * @param Car $car
     */
    public function __construct(Car $car)
    {
        $this->car = $car;
    }

    /**
     * @return array
     */
    public function getArray(): array
    {
        return [
            'color' => $this->car->getColor(),
            'type' => $this->car->getType(),
            'model' => $this->car->getModel(),
        ];
    }
}

Pemakaian

$car = new Car();
$car->setType('type#');
$car->setModel('model#1');
$car->setColor(255);

$carDecorator = new CarArrayDecorator($car);
$carResponseData = $carDecorator->getArray();

Jadi itu akan menjadi kode yang lebih indah dan lebih benar.


3

Mengonversi dan menghapus bintang yang mengganggu:

$array = (array) $object;
foreach($array as $key => $val)
{
    $new_array[str_replace('*_', '', $key)] = $val;
}

Mungkin, ini akan lebih murah daripada menggunakan refleksi.


2

Solusi singkat dari @ SpYk3HH

function objectToArray($o)
{
    $a = array();
    foreach ($o as $k => $v)
        $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v;

    return $a;
}

2

Karena banyak orang menemukan pertanyaan ini karena mengalami masalah dengan atribut akses secara dinamis dari suatu objek, saya hanya akan menunjukkan bahwa Anda dapat melakukan ini dalam PHP: $valueRow->{"valueName"}

Dalam konteks (keluaran HTML dihapus untuk dibaca):

$valueRows = json_decode("{...}"); // Rows of unordered values decoded from a JSON object

foreach ($valueRows as $valueRow) {

    foreach ($references as $reference) {

        if (isset($valueRow->{$reference->valueName})) {
            $tableHtml .= $valueRow->{$reference->valueName};
        }
        else {
            $tableHtml .= " ";
        }
    }
}

2

Dengan menggunakan typecasting Anda dapat menyelesaikan masalah Anda. Cukup tambahkan baris berikut ke objek kembali Anda:

$arrObj = array(yourReturnedObject);

Anda juga dapat menambahkan pasangan kunci dan nilai baru dengan menggunakan:

$arrObj['key'] = value;

2

Saya pikir itu ide yang bagus untuk menggunakan ciri-ciri untuk menyimpan logika konversi objek-ke-array. Contoh sederhana:

trait ArrayAwareTrait
{
    /**
     * Return list of Entity's parameters
     * @return array
     */
    public function toArray()
    {
        $props = array_flip($this->getPropertiesList());
        return array_map(
            function ($item) {
                if ($item instanceof \DateTime) {
                    return $item->format(DATE_ATOM);
                }
                return $item;
            },
            array_filter(get_object_vars($this), function ($key) use ($props) {
                return array_key_exists($key, $props);
            }, ARRAY_FILTER_USE_KEY)
        );
    }


    /**
     * @return array
     */
    protected function getPropertiesList()
    {
        if (method_exists($this, '__sleep')) {
            return $this->__sleep();
        }
        if (defined('static::PROPERTIES')) {
            return static::PROPERTIES;
        }
        return [];
    }
}

class OrderResponse
{
    use ArrayAwareTrait;

    const PROP_ORDER_ID = 'orderId';
    const PROP_TITLE = 'title';
    const PROP_QUANTITY = 'quantity';
    const PROP_BUYER_USERNAME = 'buyerUsername';
    const PROP_COST_VALUE = 'costValue';
    const PROP_ADDRESS = 'address';

    private $orderId;
    private $title;
    private $quantity;
    private $buyerUsername;
    private $costValue;
    private $address;

    /**
     * @param $orderId
     * @param $title
     * @param $quantity
     * @param $buyerUsername
     * @param $costValue
     * @param $address
     */
    public function __construct(
        $orderId,
        $title,
        $quantity,
        $buyerUsername,
        $costValue,
        $address
    ) {
        $this->orderId = $orderId;
        $this->title = $title;
        $this->quantity = $quantity;
        $this->buyerUsername = $buyerUsername;
        $this->costValue = $costValue;
        $this->address = $address;
    }

    /**
     * @inheritDoc
     */
    public function __sleep()
    {
        return [
            static::PROP_ORDER_ID,
            static::PROP_TITLE,
            static::PROP_QUANTITY,
            static::PROP_BUYER_USERNAME,
            static::PROP_COST_VALUE,
            static::PROP_ADDRESS,
        ];
    }

    /**
     * @return mixed
     */
    public function getOrderId()
    {
        return $this->orderId;
    }

    /**
     * @return mixed
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @return mixed
     */
    public function getQuantity()
    {
        return $this->quantity;
    }

    /**
     * @return mixed
     */
    public function getBuyerUsername()
    {
        return $this->buyerUsername;
    }

    /**
     * @return mixed
     */
    public function getCostValue()
    {
        return $this->costValue;
    }

    /**
     * @return string
     */
    public function getAddress()
    {
        return $this->address;
    }
}

$orderResponse = new OrderResponse(...);
var_dump($orderResponse->toArray());

1
$Menu = new Admin_Model_DbTable_Menu(); 
$row = $Menu->fetchRow($Menu->select()->where('id = ?', $id));
$Addmenu = new Admin_Form_Addmenu(); 
$Addmenu->populate($row->toArray());

Saya menganggap jawaban ini untuk catatan Doktrin (atau yang serupa).
nikoskip

1

Di sini saya telah membuat metode objectToArray () , yang juga berfungsi dengan objek rekursif, seperti ketika $objectAberisi $objectByang menunjuk ke$objectA .

Selain itu, saya membatasi output untuk properti publik menggunakan ReflectionClass. Singkirkan itu, jika Anda tidak membutuhkannya.

    /**
     * Converts given object to array, recursively.
     * Just outputs public properties.
     *
     * @param object|array $object
     * @return array|string
     */
    protected function objectToArray($object) {
        if (in_array($object, $this->usedObjects, TRUE)) {
            return '**recursive**';
        }
        if (is_array($object) || is_object($object)) {
            if (is_object($object)) {
                $this->usedObjects[] = $object;
            }
            $result = array();
            $reflectorClass = new \ReflectionClass(get_class($this));
            foreach ($object as $key => $value) {
                if ($reflectorClass->hasProperty($key) && $reflectorClass->getProperty($key)->isPublic()) {
                    $result[$key] = $this->objectToArray($value);
                }
            }
            return $result;
        }
        return $object;
    }

Untuk mengidentifikasi objek yang sudah digunakan, saya menggunakan properti yang dilindungi di kelas (abstrak) ini, bernama $this->usedObjects. Jika objek bersarang rekursif ditemukan, itu akan digantikan oleh string **recursive**. Kalau tidak, ia akan gagal karena infinite loop.


$usedObjectstidak diinisialisasi di awal, sehingga panggilan ini beberapa kali akan memberikan hasil yang salah pada panggilan selanjutnya. Selain itu, Anda tidak membebaskannya pada akhirnya, sehingga objek Anda tidak akan pernah dihapus dari memori.
HappyDog

1

Ada proposal saya, jika Anda memiliki objek di objek bahkan dengan anggota pribadi:

public function dismount($object) {
    $reflectionClass = new \ReflectionClass(get_class($object));
    $array = array();
    foreach ($reflectionClass->getProperties() as $property) {
        $property->setAccessible(true);
        if (is_object($property->getValue($object))) {
            $array[$property->getName()] = $this->dismount($property->getValue($object));
        } else {
            $array[$property->getName()] = $property->getValue($object);
        }
        $property->setAccessible(false);
    }
    return $array;
}

1

Saya menggunakan ini (diperlukan solusi rekursif dengan kunci yang tepat):

    /**
     * This method returns the array corresponding to an object, including non public members.
     *
     * If the deep flag is true, is will operate recursively, otherwise (if false) just at the first level.
     *
     * @param object $obj
     * @param bool $deep = true
     * @return array
     * @throws \Exception
     */
    public static function objectToArray(object $obj, bool $deep = true)
    {
        $reflectionClass = new \ReflectionClass(get_class($obj));
        $array = [];
        foreach ($reflectionClass->getProperties() as $property) {
            $property->setAccessible(true);
            $val = $property->getValue($obj);
            if (true === $deep && is_object($val)) {
                $val = self::objectToArray($val);
            }
            $array[$property->getName()] = $val;
            $property->setAccessible(false);
        }
        return $array;
    }

Contoh penggunaan, kode berikut:

class AA{
    public $bb = null;
    protected $one = 11;

}

class BB{
    protected $two = 22;
}


$a = new AA();
$b = new BB();
$a->bb = $b;

var_dump($a)

Akan mencetak ini:

array(2) {
  ["bb"] => array(1) {
    ["two"] => int(22)
  }
  ["one"] => int(11)
}

Bagaimana kami dapat meningkatkan fungsi Anda untuk mendukung objek dengan berbagai objek?
celsowm
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.