-
-
Save victorbstan/744478 to your computer and use it in GitHub Desktop.
<?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); |
Exactly what I was looking for. Give this man a beer.
Awesome!
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;
}`
@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.
Awesome!
Mine too! 🥇
This will not be be applicable if the properties of the object you are trying to convert are declared as private
@mdeboer Thank you
That worked for me too
$object = json_decode(json_encode($array, JSON_FORCE_OBJECT), false);
Thanks!
Works fine on PHP 5.3.29
Nice!
@victorbstan thanks man.
@mdeboer Thank you
Saved ton of my time
I love the simplicity. Thank you!
am i the only one here that minds the "wasted" cycles of json encoding + decoding?
In case of complex objects, you will have serious performance issues with json_decode(json_encode())
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;
}
Use
ArrayObject
class and cast it to array (or useArrayObject::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)
}
Use
ArrayObject
class and cast it to array (or useArrayObject::getArrayCopy()
instead). It's much much faster.
ArrayObject::getArrayCopy()
return shallow copy of array.
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
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.
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.
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
$array = json_decode(json_encode($object), true);
Absolutely brilliant. You, sir, are a genius.
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!