I am calling a magento soap v2 api and in return geting a respone with an object which I am trying to convert in associative array. But when I am trying to do that with json encode /decode method it is returning an null array.
$result = Magento::call()->catalogProductList();
$array = json_decode(json_encode($result), true);
1)The object is not empty. 2) Type casting is not an option for me because I am trying to avoid prepending *.
UPDATE
this the result value which I am trying to encode.
Tinyrocket\Magento\Objects\MagentoObjectCollection Object
(
[collection:protected] => Array
(
[0] => Tinyrocket\Magento\Objects\MagentoObject Object
(
[data:protected] => Array
(
[product_id] => 9
[sku] => Tilapia
[name] => Tilapia
[set] => 4
[type] => simple
[category_ids] => Array
(
[0] => 2
[1] => 4
)
[website_ids] => Array
(
[0] => 1
)
)
)
[1] => Tinyrocket\Magento\Objects\MagentoObject Object
(
[data:protected] => Array
(
[product_id] => 10
[sku] => Deshi Rui
[name] => Deshi Rui
[set] => 4
[type] => simple
[category_ids] => Array
(
[0] => 2
[1] => 4
)
[website_ids] => Array
(
[0] => 1
)
)
)
...
...
UPDATE 2
output of var_export($result)
Tinyrocket\Magento\Objects\MagentoObjectCollection::__set_state(array(
'collection' =>
array (
0 =>
Tinyrocket\Magento\Objects\MagentoObject::__set_state(array(
'data' =>
array (
'product_id' => '9',
'sku' => 'Tilapia',
'name' => 'Tilapia',
'set' => '4',
'type' => 'simple',
'category_ids' =>
array (
0 => '2',
1 => '4',
),
'website_ids' =>
array (
0 => '1',
),
),
)),
1 =>
Tinyrocket\Magento\Objects\MagentoObject::__set_state(array(
'data' =>
array (
'product_id' => '10',
'sku' => 'Deshi Rui',
'name' => 'Deshi Rui',
'set' => '4',
'type' => 'simple',
'category_ids' =>
array (
0 => '2',
1 => '4',
),
'website_ids' =>
array (
0 => '1',
),
),
)),
'count' => 2,
))
json_encode converted your object accordingly to its properties' visibilities.
Since Tinyrocket\Magento\Objects\MagentoObjectCollection's $collection is a protected property, its value isn't read by json_encode.
I have two solutions for this problem, one of them requires the modification of Magento's source code, so I would not recommand it, since it could create bugs, or break each time you update your CMS.
The first solution uses Reflection, so you will need PHP 5, which shouldn't be a problem since Magento needs PHP 5.4.
The following function loops through a \Tinyrocket\Magento\Objects\MagentoObjectCollection object to read all properties, and returns an array.
function magentoObjectCollectionToArray(\Tinyrocket\Magento\Objects\MagentoObjectCollection $object)
{
// The basic structure of your array.
$array = array(
'collection' => array()
);
// Since $collection is a protected property, we need to reflect it to read the value.
$collection_reflection = new \ReflectionProperty('\Tinyrocket\Magento\Objects\MagentoObjectCollection', 'collection');
// This method allows you to read protected and private properties for the current ReflectionProperty object.
$collection_reflection->setAccessible(true);
// Now we need to loop through all objects...
foreach ($collection_reflection->getValue($object) as $property => $value)
{
// Two cases : either a \Tinyrocket\Magento\Objects\MagentoObject object, or the $count property.
if ($value instanceof \Tinyrocket\Magento\Objects\MagentoObject)
{
// Same here, since $data is also a protected property, we need to reflect it.
$data_reflection = new \ReflectionProperty('\Tinyrocket\Magento\Objects\MagentoObject', 'data');
$data_reflection->setAccessible(true);
$array['collection'][$property] = array(
'data' => $data_reflection->getValue($value)
);
}
else
{
// We don't forget the $count property.
$array['collection'][$property] = $value;
}
}
// And you have your array without using JSON.
return $array;
}
Links to the PHP documentation:
ReflectionProperty::__constructReflectionProperty::setAccessibleReflectionProperty::getValueThe second solution uses JsonSerializable, so you will need PHP 5.4, which shouldn't be a problem neither.
Once the jsonSerialize method is implemented on a class which implements JsonSerializable, json_encode will encode the return value of jsonSerialize.
So, you could modify Magento's core, and make both \Tinyrocket\Magento\Objects\MagentoObjectCollection and \Tinyrocket\Magento\Objects\MagentoObject classes to implement \JsonSerializable, and adding this JsonSerialize method to their source code:
class XXX implements \JsonSerializable
{
public function JsonSerialize()
{
// Returns all variables. Since we're in the object context, we've access to all of them.
return get_object_vars($this);
}
}
Then you get your array by calling json_encode() / json_decode() as you did:
json_decode(json_encode($result), true)
While this solution may help to solve your problem, I would not recommand it since it requires modifications to Magento's core, which could break other modules and not working anymore after updating. You should instead create your own plugin and use the first solution, which is the best way to go.
Both solutions return this array:
array (
'collection' =>
array (
0 =>
array (
'data' =>
array (
'product_id' => '9',
'sku' => 'Tilapia',
'name' => 'Tilapia',
'set' => '4',
'type' => 'simple',
'category_ids' =>
array (
0 => '2',
1 => '4',
),
'website_ids' =>
array (
0 => '1',
),
),
),
1 =>
array (
'data' =>
array (
'product_id' => '10',
'sku' => 'Deshi Rui',
'name' => 'Deshi Rui',
'set' => '4',
'type' => 'simple',
'category_ids' =>
array (
0 => '2',
1 => '4',
),
'website_ids' =>
array (
0 => '1',
),
),
),
'count' => 2,
),
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With