Convert an Object to an Array - php

I am working with WordPress and since I don't believe it is possible to sort object details, I was wondering how to go about converting my Object to an Array, so that sorting can be possible.
Any help or guidance would be greatly appreciated.
I am using the WP function get_categories();
The complete content of $category is:
$category->term_id
$category->name
$category->slug
$category->term_group
$category->term_taxonomy_id
$category->taxonomy
$category->description
$category->parent
$category->count
$category->cat_ID
$category->category_count
$category->category_description
$category->cat_name
$category->category_nicename
$category->category_parent

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

If the object is not too complex (in terms of nesting) you can cast the class to an array:
$example = new StdClass();
$example->foo = 'bar';
var_dump((array) $example);
outputs:
array(1) { ["foo"]=> string(3) "bar" }
However this will only convert the base level. If you have nested objects such as
$example = new StdClass();
$example->foo = 'bar';
$example->bar = new StdClass();
$example->bar->blah = 'some value';
var_dump((array) $example);
Then only the base object will be cast to an array.
array(2) {
["foo"]=> string(3) "bar"
["bar"]=> object(stdClass)#2 (1) {
["blah"]=> string(10) "some value"
}
}
In order to go deeper, you would have to use recursion. There is a good example of an object to array conversion here.

as simple as
$array = (array)$object;
http://www.php.net/manual/en/language.types.array.php#language.types.array.casting

To convert an object to array you can use get_object_vars() (PHP manual):
$categoryVars = get_object_vars($category)

To add to #galen
<?php
$categories = get_categories();
$array = (array)$categories;
?>

To convert the entire object and all it's properties to arrays, you can use this clunky function I've had kicking around for a while:
function object_to_array($object)
{
if (is_array($object) OR is_object($object))
{
$result = array();
foreach($object as $key => $value)
{
$result[$key] = object_to_array($value);
}
return $result;
}
return $object;
}
Demo: http://codepad.org/Tr8rktjN
But for your example, with that data, you should be able to just cast to array as others have already said.
$array = (array) $object;

A less clunky way might be:
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 );
}
(Sourced from http://www.sitepoint.com/forums/showthread.php?438748-convert-object-to-array)
Note, if you'd like this as a method in a class, change the last line to:
return array_map(array($this, __FUNCTION__), $object );

Related

Combine two foreach loops for better inefficiency?

I have the following code but I am wondering how I can make it more efficient.
if ($genres){
$arr = array();
foreach ($genres as $i) {
$arr[] = $i->name;
}
$genres_arr = $arr;
}
if ($themes){
$arr = array();
foreach ($themes as $i) {
$arr[] = $i->name;
}
$themes_arr = $arr;
}
var_dump($genres_arr);
var_dump($themes_arr);
I've tried putting them into an if statement but because they both always exists only the first one runs. I want to check to see if both exist and always run them both through a foreach loop. If only one exists I want only the one to run.
These are the array structures.
["genres"]=>
array(1) {
[0]=>
object(stdClass)#1579 (2) {
["id"]=>
int(25)
["name"]=>
string(26) "Hack and slash/Beat 'em up"
}
}
["themes"]=>
array(3) {
[0]=>
object(stdClass)#1576 (2) {
["id"]=>
int(1)
["name"]=>
string(6) "Action"
}
}
I want to have them as flattered as at the moment they are inside objects. I am then going to implode them into a list for WordPress use.
This code works but its repetitive and some help would be great!
I think you can use array column because it can read values from "A multi-dimensional array or an array of objects from which to pull a column of values from" like this:
if ($genres) {
$genres_arr = array_column($genres, 'name');
}
if ($themes) {
$themes_arr = array_column($themes, 'name');
}
var_dump($genres_arr);
var_dump($themes_arr);
In this way the easiest simplification would be to introduce a new function, which builds the array.
function getNames($arr) {
if (!is_array($arra)) return false;
return array_map(function($item) {
return $item->name;
}, $arr);
}
$themes_arr = getNames($themes);
$genre_arr = getNames($genres);
This is how I would combine them
$sets = [];
if ($genres){
$sets['genres'] = $genres;
}
if ($themes){
$sets['themes'] = $themes;
}
$arr = array();
foreach( $sets as $type => $data ){
foreach ($genres as $i) {
$arr[$type][] = $i->name;
}
}
claudio's answer is perfect for this situation, but in the more general case you can also define a mapping function, which you then use with array_map for both sets of objects, e.g.
$mapper = function ($item) { return $item->name; };
$genres_arr = array_map($mapper, $genres);
$themes_arr = array_map($mapper, $themes);
This has the advantage of being able to run more complex logic (using a getter function instead of direct property access, etc), if you need it in future.
Ideally, both objects would implement a common interface, so that it was clear exactly what kinds of objects the mapping function was designed for.

PHP get keys from array in object

I've got object and I need list of it's keys.
for now I doing that in foreach
foreach($obj as $key => $attribute){
var_dump($key);
}
Is there some PHP built in function for getting object keys like array_keys for arrays?
trace
object(Solarium\QueryType\Select\Result\Document)#1383 (1) {
["fields":protected]=> array(31) { ["pdf_url"]=> string(51)
"xxxxxxxxxxxx" ["title"]=>
string(150) ......
class A
{
private $a = 1;
protected $b = 2;
public $c = 3;
}
$object = new A();
$fields = get_object_vars($object);
But by this method, you can only get public fields from your object,
i.e
print_r($fields);
Will output
Array ( [c] => 3 )
Problem is because it was
array in object.
I solve problem with this
array_keys($obj->getFields())

Apply multidimension array data to an object

For a given PHP object (loaded from CouchDB) $obj:
class stdClass#1 (3) {
public $_id =>
string(10) "nochecksum"
public $_rev =>
string(34) "1-4f734a24465bf7ba2de316fe87ffa0c1"
public $rooms =>
class stdClass#2 (1) {
public $kitchen =>
class stdClass#3 (1) {
public $ceilingFan =>
bool(false)
}
}
}
And for a given multidimensional array of data $arr, consisting of changed or new values for properties:
array(1) {
'rooms' =>
array(1) {
'kitchen' =>
array(1) {
'needsCleaning' =>
bool(true)
}
}
}
How is it possible to set $obj's properties to be values from $arr?
The solution is simple for a single dimension array:
foreach ($arr as $k=>$v) {
$obj->{$k}=$v;
}
I tried with a recursive function, but I don't know how to reference the parent(s):
$obj = setObjectFromArray($obj, $arr);
function setObjectFromArray($obj, $arr, $tree=Array())
{
foreach ($arr as $k=>$v) {
if (is_array($v)) {
$tree[]=$k;
$obj = setObjectFromArray($obj, $v, $tree);
} else {
// Here $tree is Array('rooms','kitchen')
// I want to set $obj->rooms->kitchen->{$k}
}
}
return $obj;
}
I think passing a reference of the object's property to the recursive function might work - but I don't understand either enough to make an educated guess. Any help appreciated
You could do it like this:
function setObjectFromArray($obj, $arr) {
foreach ($arr as $k => $v) {
$obj->{$k} = is_array($v) ? setObjectFromArray($obj->{$k}, $v) : $v;
}
return $obj;
}
The major difference with your code is the assignment to $obj->{$k} instead of $obj: that way you rewrite (or create) the property at each level of the recursion tree.
Be aware that even if you call the function like this:
$result = setObjectFromArray($obj, $arr);
... $obj will still have been modified and be equal to $result.
This solution is not totally obvious and maybe can fail somewhere but still - it's pair of json functions:
$r = array(
'rooms' => array(
'kitchen' => array(
'needsCleaning' => true
)
)
);
echo '<pre>',print_r(json_decode(json_encode($r))), '</pre>';
Explanation: you encode array to json-string and then decode this string to object.
Maybe you can expand this code further.

How to get function's parameters names in PHP?

I'm looking for a sort of reversed func_get_args(). I would like to find out how the parameters were named when function was defined. The reason for this is I don't want to repeat myself when using setting variables passed as arguments through a method:
public function myFunction($paramJohn, $paramJoe, MyObject $paramMyObject)
{
$this->paramJohn = $paramJohn;
$this->paramJoe = $paramJoe;
$this->paramMyObject = $paramMyObject;
}
Ideally I could do something like:
foreach (func_get_params() as $param)
$this->${$param} = ${$param};
}
Is this an overkill, is it a plain stupid idea, or is there a much better way to make this happen?
You could use Reflection:
$ref = new ReflectionFunction('myFunction');
foreach( $ref->getParameters() as $param) {
echo $param->name;
}
Since you're using this in a class, you can use ReflectionMethod instead of ReflectionFunction:
$ref = new ReflectionMethod('ClassName', 'myFunction');
Here is a working example:
class ClassName {
public function myFunction($paramJohn, $paramJoe, $paramMyObject)
{
$ref = new ReflectionMethod($this, 'myFunction');
foreach( $ref->getParameters() as $param) {
$name = $param->name;
$this->$name = $$name;
}
}
}
$o = new ClassName;
$o->myFunction('John', 'Joe', new stdClass);
var_dump( $o);
Where the above var_dump() prints:
object(ClassName)#1 (3) {
["paramJohn"]=>
string(4) "John"
["paramJoe"]=>
string(3) "Joe"
["paramMyObject"]=>
object(stdClass)#2 (0) {
}
}
Code snippet that creates an array containing parameter names as keys and parameter values as corresponding values:
$ref = new ReflectionFunction(__FUNCTION__);
$functionParameters = [];
foreach($ref->getParameters() as $key => $currentParameter) {
$functionParameters[$currentParameter->getName()] = func_get_arg($key);
}
While it's not impossible to do it, it's usually better to use another method. Here is a link to a similar question on SO :
How to get a variable name as a string in PHP?
What you could do is pass all your parameters inside of an object, instead of passing them one by one. I'm assuming you are doing this in relation to databases, you might want to read about ORMs.
get_defined_vars will give you the parameter names and their values, so you can do
$params = get_defined_vars();
foreach ($params as $var=>$val) {
$this->${var} = $val;
}

Convert multidimensional objects to array [duplicate]

This question already has answers here:
Convert a PHP object to an associative array
(33 answers)
Closed 6 months ago.
I'm using amazon product advertising api. Values are returned as a multidimensional objects.
It looks like this:
object(AmazonProduct_Result)#222 (5) {
["_code":protected]=>
int(200)
["_data":protected]=>
string(16538)
array(2) {
["IsValid"]=>
string(4) "True"
["Items"]=>
array(1) {
[0]=>
object(AmazonProduct_Item)#19 (1) {
["_values":protected]=>
array(11) {
["ASIN"]=>
string(10) "B005HNF01O"
["ParentASIN"]=>
string(10) "B008RKEIZ8"
["DetailPageURL"]=>
string(120) "http://www.amazon.com/Case-Logic-TBC-302-FFP-Compact/dp/B005HNF01O?SubscriptionId=AKIAJNFRQCIJLTY6LDTA&tag=*********-20"
["ItemLinks"]=>
array(7) {
[0]=>
object(AmazonProduct_ItemLink)#18 (1) {
["_values":protected]=>
array(2) {
["Description"]=>
string(17) "Technical Details"
["URL"]=>
string(217) "http://www.amazon.com/Case-Logic-TBC-302-FFP-Compact/dp/tech-data/B005HNF01O%3FSubscriptionId%3DAKIAJNFRQCIJLTY6LDTA%26tag%*******-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB005HNF01O"
}
}
[1]=>
object(AmazonProduct_ItemLink)#17 (1) {
["_values":protected]=>
array(2) {
I mean it also has array inside objects. I would like to convert all of them into a multidimensional array.
I know this is old but you could try the following piece of code:
$array = json_decode(json_encode($object), true);
where $object is the response of the API.
You can use recursive function like below:
function object_to_array($obj, &$arr)
{
if (!is_object($obj) && !is_array($obj))
{
$arr = $obj;
return $arr;
}
foreach ($obj as $key => $value)
{
if (!empty($value))
{
$arr[$key] = array();
objToArray($value, $arr[$key]);
}
else {$arr[$key] = $value;}
}
return $arr;
}
function convertObjectToArray($data) {
if (is_object($data)) {
$data = get_object_vars($data);
}
if (is_array($data)) {
return array_map(__FUNCTION__, $data);
}
return $data;
}
Credit to Kevin Op den Kamp.
I wrote a function that does the job, and also converts all json strings to arrays too. This works pretty fine for me.
function is_json($string) {
// php 5.3 or newer needed;
json_decode($string);
return (json_last_error() == JSON_ERROR_NONE);
}
function objectToArray($objectOrArray) {
// if is_json -> decode :
if (is_string($objectOrArray) && is_json($objectOrArray)) $objectOrArray = json_decode($objectOrArray);
// if object -> convert to array :
if (is_object($objectOrArray)) $objectOrArray = (array) $objectOrArray;
// if not array -> just return it (probably string or number) :
if (!is_array($objectOrArray)) return $objectOrArray;
// if empty array -> return [] :
if (count($objectOrArray) == 0) return [];
// repeat tasks for each item :
$output = [];
foreach ($objectOrArray as $key => $o_a) {
$output[$key] = objectToArray($o_a);
}
return $output;
}
This is an old question, but I recently ran into this and came up with my own solution.
array_walk_recursive($array, function(&$item){
if(is_object($item)) $item = (array)$item;
});
Now if $array is an object itself you can just cast it to an array before putting it in array_walk_recursive:
$array = (array)$object;
array_walk_recursive($array, function(&$item){
if(is_object($item)) $item = (array)$item;
});
And the mini-example:
array_walk_recursive($array,function(&$item){if(is_object($item))$item=(array)$item;});
In my case I had an array of stdClass objects from a 3rd party source that had a field/property whose value I needed to use as a reference to find its containing stdClass so I could access other data in that element. Basically comparing nested keys in 2 data sets.
I have to do this many times, so I didn't want to foreach over it for each item I need to find. The solution to that issue is usually array_column, but that doesn't work on objects. So I did the above first.
Just in case you came here as I did and didn't find the right answer for your situation, this modified version of one of the previous answers is what ended up working for me:
protected function objToArray($obj)
{
// Not an object or array
if (!is_object($obj) && !is_array($obj)) {
return $obj;
}
// Parse array
foreach ($obj as $key => $value) {
$arr[$key] = $this->objToArray($value);
}
// Return parsed array
return $arr;
}
The original value is a JSON string. The method call looks like this:
$array = $this->objToArray(json_decode($json, true));

Categories