Skip to content

Instantly share code, notes, and snippets.

@victorbstan
Created December 17, 2010 04:18
Show Gist options
  • Select an option

  • Save victorbstan/744478 to your computer and use it in GitHub Desktop.

Select an option

Save victorbstan/744478 to your computer and use it in GitHub Desktop.
recursively cast a PHP object to array
<?php
/*
This function saved my life.
found on: http://www.sitepoint.com/forums//showthread.php?t=438748
by: crvandyke
It takes an object, and when all else if/else/recursive functions fail to convert the object into an associative array, this one goes for the kill. Who would'a thunk it?!
*/
$array = json_decode(json_encode($object), true);
@dsteplight

Copy link
Copy Markdown

Do you know how many times I've had to do this over the past few years and it was ugly. This is definitely a life saver!

@citronkaste

Copy link
Copy Markdown

Exactly what I was looking for. Give this man a beer.

@okoddcat

Copy link
Copy Markdown

Awesome!

@TwanoO67

Copy link
Copy Markdown

Just tried over some nested objects/array and it didn't work.
But this does (not as elegant, but more effective):

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

//permet de changer les private en public, pour un meuilleur conversion des object en array
private 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;
}`

@mdeboer

mdeboer commented Aug 7, 2016

Copy link
Copy Markdown

@TwanoO67 I had the same issue when converting an array to object using the code below. It only converted the outer most array to object and not the nested arrays.

$object = json_decode(json_encode($array), false);

I solved this by using:

$object = json_decode(json_encode($array, JSON_FORCE_OBJECT), false);

I'm pretty sure the solution would be similar when converting from object to array.

@sajjad-dehghani

Copy link
Copy Markdown

Awesome!

@ChristopherDosin

Copy link
Copy Markdown

Mine too! 🥇

@inonbaguio

Copy link
Copy Markdown

This will not be be applicable if the properties of the object you are trying to convert are declared as private

@christoferd

Copy link
Copy Markdown

@mdeboer Thank you
That worked for me too

$object = json_decode(json_encode($array, JSON_FORCE_OBJECT), false);

@bonatoc

bonatoc commented Jan 25, 2018

Copy link
Copy Markdown

Thanks!
Works fine on PHP 5.3.29

@arnisjuraga

Copy link
Copy Markdown

Nice!

@fendis0709

Copy link
Copy Markdown

@victorbstan thanks man.

@anver

anver commented Jul 29, 2018

Copy link
Copy Markdown

@mdeboer Thank you
Saved ton of my time

@quasi635

quasi635 commented Aug 8, 2018

Copy link
Copy Markdown

I love the simplicity. Thank you!

@desjob

desjob commented Oct 5, 2018

Copy link
Copy Markdown

am i the only one here that minds the "wasted" cycles of json encoding + decoding?

@Okipa

Okipa commented Dec 10, 2018

Copy link
Copy Markdown

In case of complex objects, you will have serious performance issues with json_decode(json_encode())

@yoshkinawa

Copy link
Copy Markdown

Use this function to access also private and protected arguments

function obj2arr( $obj, $nestLevel = 0 ) {

// limit nesting level (for performance and not to go over the maximum)
if ( $nestLevel > 15 ) return;

// if current member is an object - turn it to an array
if( is_object( $obj ) ) $obj = (array) $obj;

// if current member is an array - recursively call this function to each of his children
if( is_array( $obj ) ) {

	$return = [];

	foreach( $obj as $key => $val ) {

		// correct private and protected key names
		$aux = explode ( "\0", $key );
		$newkey = $aux[ count( $aux ) - 1 ];
		$return[ $newkey ] = obj2arr( $val, $nestLevel + 1 );

	}

} else $return = $obj;

// return transformed object
return $return;

}

@scmrus

scmrus commented Aug 29, 2019

Copy link
Copy Markdown

Use ArrayObject class and cast it to array (or use ArrayObject::getArrayCopy() instead). It's much much faster.

php > $x = [1, (object) ['x'=>'y'], 3];
php > var_dump($x);
array(3) {
  [0] =>
  int(1)
  [1] =>
  class stdClass#1 (1) {
    public $x =>
    string(1) "y"
  }
  [2] =>
  int(3)
}
php > var_dump((new ArrayObject($x))->getArrayCopy());
array(3) {
  [0] =>
  int(1)
  [1] =>
  class stdClass#1 (1) {
    public $x =>
    string(1) "y"
  }
  [2] =>
  int(3)
}

@c01nd01r

c01nd01r commented Sep 2, 2019

Copy link
Copy Markdown

Use ArrayObject class and cast it to array (or use ArrayObject::getArrayCopy() instead). It's much much faster.

ArrayObject::getArrayCopy() return shallow copy of array.

@machitgarha

Copy link
Copy Markdown

@scmrus and @c01nd01r
I actually understood this after trying it, but I forgot to remove the comment from here. Sorry.
BTW, a recursive function in PHP is faster than the JSON way.

@holtz-mb

Copy link
Copy Markdown

Be care full if use encodings other than UTF-8. If you use that, json_encode will return false.

See here https://www.php.net/manual/de/function.json-encode.php#115733

@WhereJuly

WhereJuly commented Mar 25, 2020

Copy link
Copy Markdown

This will not be be applicable if the properties of the object you are trying to convert are declared as private

You could always create the getter for the object like this (implemented in a form of an universal trait)

trait ThrowingGetter
{
    public function __get($propertyName)
    {
        if (property_exists($this, $propertyName)) {
            return $this->$propertyName;
        }
        throw new \UnexpectedValueException(sprintf('Niceprice: The property \'%s\' does not exist on %s class.', $propertyName, __CLASS__));
    }
}

And use it in as many objects as you like (use ThrowingGetter).

This way you keep your object immutable, read-only.

@WhereJuly

Copy link
Copy Markdown

The initial

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

will not work straight like this if your nested objects are custom, not stdClass type objects. For this to work on these too you should implement JsonSerializable interface on your custom nested objects. See the respective PHP documentation.

@iam-raihan

iam-raihan commented Aug 3, 2020

Copy link
Copy Markdown

just in case performance matters

function objectToArray($object)
{
    if(!is_object($object) && !is_array($object)) {
        return $object;
    }

    return array_map('objectToArray', (array) $object);
}

from SO

@jonyen

jonyen commented Dec 29, 2020

Copy link
Copy Markdown

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

Absolutely brilliant. You, sir, are a genius.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment