Convert a PHP object to an associative array

后端 未结 30 1577
走了就别回头了
走了就别回头了 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:40

    For your case it was right/beautiful if you would use the "decorator" or "date model transformation" patterns. For example:

    Your model

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

    Decorator

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

    Usage

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

    So it will be more beautiful and more correct code.

    0 讨论(0)
  • 2020-11-22 02:40

    Converting and removing annoying stars:

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

    Probably, it will be cheaper than using reflections.

    0 讨论(0)
  • 2020-11-22 02:41

    If your object properties are public you can do:

    $array =  (array) $object;
    

    If they are private or protected, they will have weird key names on the array. So, in this case you will need the following function:

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

    I think it is a nice idea to use traits to store object-to-array converting logic. A simple example:

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

    What about get_object_vars($obj)? It seems useful if you only want to access the public properties of an object.

    See get_object_vars.

    0 讨论(0)
  • 2020-11-22 02:43

    Use:

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

    It returns an array without special characters and class names.

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