Convert object to array

Hi

Can anyone tell me if there is an easy way to convert an object into an array.

I currently have the following object:-

stdClass Object
(
    [documentFiltering] =>
    [searchComments] =>
    [estimatedTotalResultsCount] => 17900000
    [estimateIsExact] =>
    [resultElements] => Array
        (
            [0] => stdClass Object
                (
                    [summary] =>
                     => http://www.test.com/
                    [snippet] => Provides extranet privacy to clients making a range of <b>tests</b> and surveys available <br>  to their human resources departments. Companies can <b>test</b> prospective and <b>...</b>
                    [title] => <b>Test</b> Central Home
                    [cachedSize] => 39k
                    [relatedInformationPresent] => 1
                    [hostName] =>
                    [directoryCategory] => stdClass Object
                        (
                            [fullViewableName] =>
                            [specialEncoding] =>
                        )

                    [directoryTitle] =>
                )

            [1] => stdClass Object
                (
                    [summary] =>
                     => http://www.bandwidthplace.com/speedtest/
                    [snippet] => Personal <b>Test</b>. <b>Test</b> the speed of your Internet connection Free up to 3 times a <br>  month Purchase a subscription for. Up to 1000 <b>tests</b> per month; Personal <b>test</b> <b>...</b>
                    [title] => Bandwidth Speed <b>Test</b>
                    [cachedSize] => 15k
                    [relatedInformationPresent] => 1
                    [hostName] =>
                    [directoryCategory] => stdClass Object
                        (
                            [fullViewableName] =>
                            [specialEncoding] =>
                        )

                    [directoryTitle] =>
                )

            [2] => stdClass Object
                (
                    [summary] =>
                     => http://www.innergeek.us/geek.html
                    [snippet] => Geeks everywhere have taken the Original Geek <b>Test</b>, a comprehensive 507-point <br>  survey of how geeky you are. Possible ranks include Geekish Tendencies, Geek, <b>...</b>
                    [title] => Geek Out with the Original Geek <b>Test</b>
                    [cachedSize] => 10k
                    [relatedInformationPresent] => 1
                    [hostName] =>
                    [directoryCategory] => stdClass Object
                        (
                            [fullViewableName] =>
                            [specialEncoding] =>
                        )

                    [directoryTitle] =>
                )

        )

    [searchQuery] => test
    [startIndex] => 1
    [endIndex] => 3
    [searchTips] =>
    [directoryCategories] => Array
        (
        )

    [searchTime] => 0.026511
)

As you can see the object contains various items some of which are arrays, I wish the objects within these arrays to be converted into arrays as well (ie it should recursively go through all arrays and objects and convert the content into arrays if need be).

I have created the following code:-

function object_2_array($result)
{
	$array = array();
	foreach ($result as $key=>$value)
	{
		if (is_object($value))
		{
			$array[$key]=object_2_array($value);
		}
		if (is_array($value))
		{
			$array[$key]=object_2_array($value);
		}
		else
		{
			$array[$key]=$value;
		}
	}
	return $array;
}

but it does not convert the objects within the array probably for some silly reason that I cannot currently see.

May I ask WHY you want to convert to an array? I only ask because I was stuck in a similar situation where I actually didn’t need to do the convert after all.

I am making a class that decides wether to use nusoap or php soap extension (if php soap extension is not available it uses nusoap). nusoap returns results as an array but php’s soap extension returns results as posted above (unless I am missing something and that can be changed?).

For the class I am working on to be complete I really need for the data to be returned in 1 format regardless of the extension used (otherwise I will have to programatically check in any script I use wether an object or array was returned and deal with it that which will cause excess code and confusion).

u can cast know. ie … (array)Object

what version of php are you using?

If you are using 5, then have a look at SPL’s ArrayObject.

Where you can do stuff like this:



$testArray = array('test1','test2','test3');
$obj = new ArrayObject($testArray);

foreach($obj as $data) {
	echo $data; // echo's 'test1test2test3'
}


$foo = new foo;
$arr = (array) $foo;

you may need to cast the nested objects to arrays as well.

casting the object to an array just seems to actually create an empty array. I receive the object just like in post 1 and do not have the ability to change the format it is returned in hence why i have to restructure after I receive it.

Unfortunately part of the problem is also I will not know if php 4 or php 5 is being used and need the code compatible with both.

Unfortunately part of the problem is also I will not know if php 4 or php 5 is being used and need the code compatible with both.

Oh alright. Well let’s review the problem domain again then.

Based on this code sample:


function object_2_array($result)
{
    $array = array();
    foreach ($result as $key=>$value)
    {
       # if $value is an object then
        if (is_object($value))
        {
            #run the $value through the function again.
            $array[$key]=object_2_array($value);
        }

       # if $value is an array then
        if (is_array($value))
        {
            #run the $value through the function again??????
            $array[$key]=object_2_array($value);
        }

       # if $value is not an array then (it also includes objects)
        else
        {
            $array[$key]=$value;
        }
    }
    return $array;
}

Your checking order is incorrect. You are checking to see if $value is an object then overwriting it with the else statement in your next if else block.

Try rearranging your if statement so that it looks something like this:


function object_2_array($result)
{
    $array = array();
    foreach ($result as $key=>$value)
    {
       # if $value is an array then
        if (is_array($value))
        {
            #you are feeding an array to object_2_array function it could potentially be a perpetual loop.
            $array[$key]=object_2_array($value);
        }

       # if $value is not an array then (it also includes objects)
        else
        {
       # if $value is an object then
        if (is_object($value))
        {
            $array[$key]=object_2_array($value);
        } else {

            $array[$key]=$value;
}
        }
    }
    return $array;
}

By the way, did you know that you are doing a recursive function call when $value is an array? That could get you stuck into a perpetual loop.

HTH.

oh no wait… I’ve noticed that BEFORE reordering your if statements… n/m it’s 2 am here :stuck_out_tongue:

HTH anyway.

OMG rvdavid you are a genius and you don’t even know it. Your post brought to my attention that I am using an if instead of elseif for some strange reason. I have changed this and it works with no problem at all now, I have no idea why I did not notice this before.

Revised:-

function object_2_array($result)
{
	$array = array();
	foreach ($result as $key=>$value)
	{
		if (is_object($value))
		{
			$array[$key]=object_2_array($value);
		}
		elseif (is_array($value))
		{
			$array[$key]=object_2_array($value);
		}
		else
		{
			$array[$key]=$value;
		}
	}
	return $array;
}

The above seems to work as expected.

Why not this:

function object_2_array($result)
{
    $array = array();
    foreach ($result as $key=>$value)
    {
        if (is_object($value) || is_array($value))
        {
            $array[$key]=object_2_array($value);
        }
        else
        {
            $array[$key]=$value;
        }
    }
    return $array;
}

Or this:

function object_2_array($data)
{
	if(is_array($data) || is_object($data))
	{
		$result = array();
		foreach ($data as $key => $value)
		{
			$result[$key] = object_2_array($value);
		}
		return $result;
	}else{
		return $data;
	}
}

Or without the else:


function object_2_array($data)
{
	if(is_array($data) || is_object($data))
	{
		$result = array();
		foreach ($data as $key => $value)
		{
			$result[$key] = object_2_array($value);
		}
		return $result;
	}
	return $data;
}

Fenrir2 I have the elseif there as when I originally started writing it I did not realize arrays would cause any problem (or that they would be returned) so I added that elseif in. As time goes on I will be trying to streamline it a bit.

OMG rvdavid you are a genius and you don’t even know it. Your post brought to my attention that I am using an if instead of elseif for some strange reason. I have changed this and it works with no problem at all now, I have no idea why I did not notice this before.

:slight_smile: glad it worked with no probs for you.

As time goes on I will be trying to streamline it a bit.

when you refactor, keep in mind that objects are allowed to have certain responsibilities,

So next time, instead of creating a generic “object to array” function/method outside of the SOAP objects, maybe you can add a specialised “toArray()” method to each/or one of the SOAP classes instead of creating a converter object which tries to understand how the two objects work.

I am making a class that decides wether to use nusoap or php soap extension (if php soap extension is not available it uses nusoap). nusoap returns results as an array.

If that is all the class does, then maybe you can glue it onto a lower level class because by the sounds of it, it doesn’t warrant an object.

Off the top of my head, I’d suggest that you write up a decorator for the PHP SOAP object and add a “toArray()” or “export()” method which does the object to array conversion without having to perform logic on if it is or is not an object.

Or perhaps yuo could go the other way, and throw the array produced by NUSOAP into a DataSpace() class - which is really a glorified hash or create a decorator which uses the array exported by NUSOAP to match the way PHPSOAP’s properties and object structure are organised.

If you were looking to streamline, refactor responsibilities so that they are not so general.

regards,

This function will only be kicked in if php’s built in soap is used. I have taken the function out of the class to make it easier to work with.

I had to convert an object to an array for better handling when I received an simpleXML object from a web service so I used this function below:


function objectToArray($object)
{
  if(!is_object( $object ) && !is_array( $object ))
  {
      return $object;
  }
  if(is_object($object) )
  {
      $object = get_object_vars( $object );
  }
  return array_map('objectToArray', $object );
}

Maybe it helps someone.

I know this is an old thread, but hopefully this will help someone. In my experience, this is the best way to recursively cast an object to an array.

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