Converti un oggetto PHP in un array associativo


761

Sto integrando un'API nel mio sito Web che funziona con i dati archiviati negli oggetti mentre il mio codice viene scritto usando array.

Vorrei una funzione quick-and-dirty per convertire un oggetto in un array.

Risposte:


1392

Basta digitarlo

$array = (array) $yourObject;

Dagli array :

Se un oggetto viene convertito in un array, il risultato è un array i cui elementi sono proprietà dell'oggetto. Le chiavi sono i nomi delle variabili dei membri, con alcune notevoli eccezioni: le proprietà di interi sono inaccessibili; le variabili private hanno il nome della classe anteposto al nome della variabile; le variabili protette hanno un '*' anteposto al nome della variabile. Questi valori anteposti hanno byte nulli su entrambi i lati.

Esempio: oggetto semplice

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

var_dump( (array) $object );

Produzione:

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

Esempio: oggetto complesso

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 (con \ 0s modificato per chiarezza):

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

Uscita con var_exportinvece di var_dump:

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

La tipografia in questo modo non eseguirà il casting approfondito del grafico degli oggetti e sarà necessario applicare i byte null (come spiegato nel preventivo manuale) per accedere ad eventuali attributi non pubblici. Quindi funziona meglio quando si lanciano oggetti StdClass o oggetti con solo proprietà pubbliche. Per veloce e sporco (quello che hai chiesto) va bene.

Vedi anche questo post di blog approfondito:


3
Considera anche l' ArrayAccessinterfaccia, forse in combinazione con questa soluzione. php.net/manual/en/class.arrayaccess.php
alttag

3
Se hai delle chiavi intere, queste verranno convertite in stringhe e questo può causare grossi problemi. Per esempio[1 => "one"] diventa["1" => "one"]
Oleg l'

2
@Howie Typecasting con (array)e (object)funziona in modo affidabile e lo stesso in tutte le versioni dal PHP 4.3. Vedi 3v4l.org/X6lhm . Se ricevi un errore di sintassi, hai fatto qualcosa di sbagliato.
Gordon,

2
@Howie vedi la sezione Log delleempty modifiche per . Non è possibile utilizzare un'espressione emptyprecedente alla 5.5. Questo è completamente estraneo al typecasting;)
Gordon,

4
Typecast. Sì. Digitare Freakin CAST! Buona. +1
Kaushik Makwana,

346

È possibile convertire rapidamente oggetti profondamente nidificati in array associativi facendo affidamento sul comportamento delle funzioni di codifica / decodifica JSON:

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

12
Questa è la soluzione migliore se vuoi una conversione ricorsiva approfondita (e ovviamente non ti preoccupare delle cattive prestazioni)
Julian Habekost,

2
questo mi ha aiutato totalmente con la mia situazione, grazie mille.
Cesar Bielich,

9
Rispettosamente, penso che funzioni ancora ... non dimenticare di impostare il secondo parametro su true.
Kirk B,

3
Il secondo parametro ha risolto il problema, funzionando con PHP 5.6.25. Grazie!
Ju Oliveira,

3
Funziona perfettamente per oggetti nidificati! Grazie!
Melody,

68

Dal primo hit di Google per " Oggetto PHP per assoc array " abbiamo questo:

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

La fonte è su codesnippets.joyent.com .


16
Personalmente, non mi piace l'idea di richiamare la funzione per ogni valore. Ho una versione simile, ma in 3 righe: function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }questo imposta semplicemente tutto ciò che non è un oggetto o un array e continua senza richiami ripetitivi al metodo se non necessario.
SpYk3HH,

13
@ SpYk3HH: scrivi la tua risposta?
DanMan,

2
Il primo successo per "php object to assoc array" è stackoverflow.com/questions/4345554/…
Chris

Questa (e la versione di @ SpYk3HH) sembra funzionare anche più lentamente rispetto all'opzione json_encode ( stackoverflow.com/a/16111687/470749 ). Non so perché questi approcci sarebbero mai stati preferibili.
Ryan,

1
@Ryan json codifica e decodifica non funzionerà con i valori NaN e INFINITE per float e potenzialmente potrebbe avere altri problemi che non riesco a pensare dalla cima della mia testa, ma per molti casi potrebbe essere un'opzione migliore. Per quanto riguarda l'ottimizzazione, ciò di cui ha bisogno è il contesto: lasciami collegare un post che ho scritto su questo argomento evidentemente cubo.com/blog/game-optimization/when-to-optimize . l'essere tl; dr, non ottimizzare le cose che non richiedono enormi quantità di tempo di esecuzione perché i vantaggi non hanno senso nel contesto dell'intera applicazione.
Maurycy,

61

Se le proprietà del tuo oggetto sono pubbliche puoi fare:

$array =  (array) $object;

Se sono privati ​​o protetti, avranno nomi di chiavi strani sull'array. Quindi, in questo caso avrai bisogno della seguente funzione:

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

Se la tua proprietà è protetta, setAccessible (false) la cambierà in visibilità protetta? o lo renderà privato?
Nick Mitchell,

L'unica soluzione che ho trovato, che ha funzionato con proprietà protette. Grazie
dav

3
migliore soluzione per variabili private e protette !!
HIRA THAKUR,

Qui la riga $ property-> setAccessible (false); sarà eseguito su ogni proprietà - anche se fosse pubblica ...
Francois Bourgeois,

Eccellente ... Fantastico ... Fantastico. Grazie.
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());

Produzione

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

1
Pro e contro di questa soluzione? Che dire di una classe dichiarata come classe Test {const A = 1; public $ parent = new Test (); }
Matteo Gaggiano il

13

Ecco un po 'di codice:

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

funziona meglio per me (ma dovevo rimuovere "xxx" e restituire $ $)
Gerfried

12

Tutte le altre risposte pubblicate qui funzionano solo con attributi pubblici. Ecco una soluzione che funziona con oggetti simili a JavaBeans usando reflection e 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;
}

Sì, ma ... se stai usando l'Oggetto / Matrice come variabile, che è anche ciò che porta tutto questo, perché hai bisogno di qualcosa di diverso dalle publicproprietà?
SpYk3HH,

@ SpYk3HH: non ho posto la domanda. Non so nemmeno perché qualcuno preferirebbe un array piuttosto che un oggetto.
Francois Bourgeois,

Eh, spesso preferisco convertire i risultati delle query in array solo per fornire un "elenco" uniforme per il loop-through, poiché la maggior parte delle altre cose in un'app che deve essere "loop" tendono ad essere array. Rende semplice la scrittura di "metodi di loop universali". Spesso, se sto usando un oggetto, non eseguo il ciclo tra le sue proprietà, lo sto usando come oggetto e utilizzo quelle proprietà secondo necessità.
SpYk3HH,

11

Che dire get_object_vars($obj)? Sembra utile se si desidera accedere solo alle proprietà pubbliche di un oggetto.

Vedi get_object_vars .


10

Digita cast il tuo oggetto su un array.

$arr =  (array) $Obj;

Risolverà il tuo problema.


5
No, non lo sarà se hai proprietà private o protette.
forsberg,

2
Soluzione più semplice. Grazie
ASD

6

Prima di tutto, se hai bisogno di un array da un oggetto, probabilmente dovresti costituire prima i dati come un array. Pensaci.

Non utilizzare foreachun'istruzione o trasformazioni JSON. Se stai pianificando questo, di nuovo stai lavorando con una struttura di dati, non con un oggetto.

Se ne hai davvero bisogno, usa un approccio orientato agli oggetti per avere un codice pulito e gestibile. Per esempio:

Oggetto come matrice

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

Se hai bisogno di tutte le proprietà, usa un oggetto transfer:

class PersonTransferObject
{
    private $person;

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

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

 }

6

Puoi facilmente usare questa funzione per ottenere il risultato:

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

Usa PHP 5 o successivo.


5

Ecco la mia funzione PHP ricorsiva per convertire oggetti PHP in un array associativo:

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

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

Esempio di utilizzo:

// ---- 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
.. o l'oneliner:$new_arr1 = (array) $my_object;
FooBar

1
La versione oneliner è poco profonda, quindi non equivalente.
Jonathan Lidbeck,

5

Per convertire un oggetto in array basta semplicemente lanciarlo esplicitamente:

$name_of_array = (array) $name_of_object;

5

Puoi anche creare una funzione in PHP per convertire un array di oggetti:

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

@ Akintunde-Rotimi, ho creato una funzione comune e mostrato.
Rakhi Prajapati,

4

È possibile che si desideri eseguire questa operazione quando si ottengono dati come oggetti dai 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
C'è una risposta accettata con 41 voti, non 1 o 10, 41. Cosa aggiunge la tua risposta?
Yaroslav l'

4

Funzione personalizzata per convertire stdClass in un 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;
    }
}

Un'altra funzione personalizzata per convertire l'array in 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;
    }
}

Esempio di utilizzo:

// 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

Uso:

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

Restituisce un array senza caratteri speciali e nomi di classe.


4

Questa risposta è solo l'unione delle diverse risposte di questo post, ma è la soluzione per convertire un oggetto PHP con proprietà pubbliche o private con valori o matrici semplici in un array associativo ...

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

Alcuni miglioramenti al codice "ben informato"

/*** 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

Si noti che se la funzione è membro di una classe (come sopra) è necessario passare __FUNCTION__a__METHOD__


3

Inoltre puoi usare The Symfony Serializer Component

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

Per il tuo caso era giusto / bello usare i motivi "decoratore" o "trasformazione modello data". Per esempio:

Il tuo modello

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

Decoratore

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(),
        ];
    }
}

uso

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

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

Quindi sarà il codice più bello e più corretto.


3

Convertire e rimuovere stelle fastidiose:

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

Probabilmente, sarà più economico rispetto all'utilizzo dei riflessi.


2

Breve soluzione di @ 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

Poiché molte persone trovano questa domanda a causa di problemi con l'accesso dinamico agli attributi di un oggetto, farò solo notare che puoi farlo in PHP: $valueRow->{"valueName"}

Nel contesto (output HTML rimosso per leggibilità):

$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

Usando il typecasting puoi risolvere il tuo problema. Aggiungi le seguenti righe all'oggetto return:

$arrObj = array(yourReturnedObject);

Puoi anche aggiungere una nuova chiave e una nuova coppia di valori usando:

$arrObj['key'] = value;

2

Penso che sia una buona idea usare i tratti per memorizzare la logica di conversione da oggetto a array. Un semplice esempio:

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

Suppongo quale sia questa risposta per un documento di Dottrina (o simile).
nikoskip,

1

Qui ho creato un metodo objectToArray () , che funziona anche con oggetti ricorsivi, come quando $objectAcontiene $objectBche punta di nuovo a$objectA .

Inoltre ho limitato l'output alle proprietà pubbliche usando ReflectionClass. Sbarazzati di esso, se non ti serve.

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

Per identificare oggetti già usati, sto usando una proprietà protetta in questa classe (astratta), chiamata $this->usedObjects. Se viene trovato un oggetto nidificato ricorsivo, verrà sostituito dalla stringa **recursive**. Altrimenti fallirebbe a causa del loop infinito.


$usedObjectsnon viene inizializzato all'inizio, quindi chiamare questo più volte darà risultati errati nelle chiamate successive. Inoltre, non lo libererai alla fine, quindi i tuoi oggetti non verranno mai rimossi dalla memoria.
HappyDog,

1

Ecco la mia proposta, se hai oggetti negli oggetti con membri anche privati:

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

Uso questo (necessaria soluzione ricorsiva con le chiavi appropriate):

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

Esempio di utilizzo, il seguente codice:

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)

Stampa questo:

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

Come possiamo aggiornare la tua funzione per supportare oggetti con array di oggetti?
celsowm
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.