将对象转换为关联数组 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,
  ),
)