将对象转换为关联数组 returns 空值
Convert object to associative array returns null value
我正在调用 magento soap v2 api 并在 return 中得到一个对象的响应,我试图在关联数组中转换该对象。但是当我试图用 json 编码/解码方法做到这一点时,它是 returning 一个空数组。
$result = Magento::call()->catalogProductList();
$array = json_decode(json_encode($result), true);
1)对象不为空。
2) 类型转换对我来说不是一个选项,因为我试图避免在 *.
前面加上
更新
这是我尝试编码的结果值。
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
)
)
)
...
...
更新 2
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,
))
我们可以使用 for 循环遍历对象 .. in ,并创建包含数据的关联数组。一个例子:
class exampleClass
{
public $var = 'default value';
public function showVar() {
echo $this->var;
}
}
$a = new exampleClass();
$array = json_decode(json_encode($a), true);
print_r($array);
如果你确定 $result 对象不为空,你可以试试
$array = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', json_encode($result)), true );
json_encode
根据其属性的可见性转换您的对象。
由于 Tinyrocket\Magento\Objects\MagentoObjectCollection
的 $collection
是一个受保护的 属性,它的值不会被 json_encode
读取。
对于这个问题我有两个解决方案,其中一个需要修改 Magento 的源代码,所以我不推荐它,因为它可能会产生错误,或者每次更新 CMS 时都会中断。
第一个解决方案使用Reflection
, so you will need PHP 5, which shouldn't be a problem since Magento needs PHP 5.4。
以下函数循环遍历 \Tinyrocket\Magento\Objects\MagentoObjectCollection
对象以读取所有属性,并且 return 是一个数组。
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;
}
指向 PHP 文档的链接:
第二个解决方案使用 JsonSerializable
,因此您将需要 PHP 5.4,这也不成问题。
在实现 JsonSerializable 的 class 上实现 jsonSerialize
方法后,json_encode
将对 jsonSerialize
的 return 值进行编码。
所以,你可以修改 Magento 的核心,让 \Tinyrocket\Magento\Objects\MagentoObjectCollection
和 \Tinyrocket\Magento\Objects\MagentoObject
classes 实现 \JsonSerializable
,并添加这个 JsonSerialize
方法他们的源代码:
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);
}
}
然后你通过调用 json_encode()
/ json_decode()
得到你的数组:
json_decode(json_encode($result), true)
虽然此解决方案可能有助于解决您的问题,但我不会推荐它,因为它需要修改 Magento 的核心,这可能会破坏其他模块并且在更新后不再工作。
您应该改为创建自己的插件并使用第一个解决方案,这是最好的方法。
两种解决方案return 这个数组:
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,
),
)
我正在调用 magento soap v2 api 并在 return 中得到一个对象的响应,我试图在关联数组中转换该对象。但是当我试图用 json 编码/解码方法做到这一点时,它是 returning 一个空数组。
$result = Magento::call()->catalogProductList();
$array = json_decode(json_encode($result), true);
1)对象不为空。 2) 类型转换对我来说不是一个选项,因为我试图避免在 *.
前面加上更新
这是我尝试编码的结果值。
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
)
)
)
...
...
更新 2
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,
))
我们可以使用 for 循环遍历对象 .. in ,并创建包含数据的关联数组。一个例子:
class exampleClass
{
public $var = 'default value';
public function showVar() {
echo $this->var;
}
}
$a = new exampleClass();
$array = json_decode(json_encode($a), true);
print_r($array);
如果你确定 $result 对象不为空,你可以试试
$array = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', json_encode($result)), true );
json_encode
根据其属性的可见性转换您的对象。
由于 Tinyrocket\Magento\Objects\MagentoObjectCollection
的 $collection
是一个受保护的 属性,它的值不会被 json_encode
读取。
对于这个问题我有两个解决方案,其中一个需要修改 Magento 的源代码,所以我不推荐它,因为它可能会产生错误,或者每次更新 CMS 时都会中断。
第一个解决方案使用Reflection
, so you will need PHP 5, which shouldn't be a problem since Magento needs PHP 5.4。
以下函数循环遍历 \Tinyrocket\Magento\Objects\MagentoObjectCollection
对象以读取所有属性,并且 return 是一个数组。
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;
}
指向 PHP 文档的链接:
第二个解决方案使用 JsonSerializable
,因此您将需要 PHP 5.4,这也不成问题。
在实现 JsonSerializable 的 class 上实现 jsonSerialize
方法后,json_encode
将对 jsonSerialize
的 return 值进行编码。
所以,你可以修改 Magento 的核心,让 \Tinyrocket\Magento\Objects\MagentoObjectCollection
和 \Tinyrocket\Magento\Objects\MagentoObject
classes 实现 \JsonSerializable
,并添加这个 JsonSerialize
方法他们的源代码:
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);
}
}
然后你通过调用 json_encode()
/ json_decode()
得到你的数组:
json_decode(json_encode($result), true)
虽然此解决方案可能有助于解决您的问题,但我不会推荐它,因为它需要修改 Magento 的核心,这可能会破坏其他模块并且在更新后不再工作。 您应该改为创建自己的插件并使用第一个解决方案,这是最好的方法。
两种解决方案return 这个数组:
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,
),
)