Convert a PHP object to an associative array

后端 未结 30 1575
走了就别回头了
走了就别回头了 2020-11-22 02:18

I\'m integrating an API to my website which works with data stored in objects while my code is written using arrays.

I\'d like a quick-and-dirty function to convert

相关标签:
30条回答
  • 2020-11-22 02:43

    Short solution of @SpYk3HH

    function objectToArray($o)
    {
        $a = array();
        foreach ($o as $k => $v)
            $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v;
    
        return $a;
    }
    
    0 讨论(0)
  • 2020-11-22 02:44

    First of all, if you need an array from an object you probably should constitute the data as an array first. Think about it.

    Don't use a foreach statement or JSON transformations. If you're planning this, again you're working with a data structure, not with an object.

    If you really need it use an object-oriented approach to have a clean and maintainable code. For example:

    Object as array

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

    If you need all properties, use a transfer object:

    class PersonTransferObject
    {
        private $person;
    
        public function __construct(Person $person) {
            $this->person = $person;
        }
    
        public function toArray() {
            return [
                // 'name' => $this->person->getName();
            ];
        }
    
     }
    
    0 讨论(0)
  • 2020-11-22 02:47

    Custom function to convert stdClass to an 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;
        }
    }
    

    Another custom function to convert Array to 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;
        }
    }
    

    Usage Example:

    // 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);
    
    0 讨论(0)
  • 2020-11-22 02:48
    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());
    

    Output

    array(2) {
        ["b"]=>
        string(3) "two"
        ["Testc"]=>
        int(1)
    }
    array(1) {
        ["b"]=>
        string(3) "two"
    }
    
    0 讨论(0)
  • 2020-11-22 02:50

    Since a lot of people find this question because of having trouble with dynamically access attributes of an object, I will just point out that you can do this in PHP: $valueRow->{"valueName"}

    In context (removed HTML output for readability):

    $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 .= " ";
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:50

    Here I've made an objectToArray() method, which also works with recursive objects, like when $objectA contains $objectB which points again to $objectA.

    Additionally I've restricted the output to public properties using ReflectionClass. Get rid of it, if you don't need it.

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

    To identify already used objects, I am using a protected property in this (abstract) class, named $this->usedObjects. If a recursive nested object is found, it will be replaced by the string **recursive**. Otherwise it would fail in because of infinite loop.

    0 讨论(0)
提交回复
热议问题