将对象转换为关联数组返回null值

时间:2021-02-19 21:19:11

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.

我正在调用一个magento soap v2 api,并作为回报,我正在尝试使用关联数组转换对象。但是当我尝试使用json编码/解码方法时,它返回一个空数组。

$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 *.

1)对象不是空的。 2)类型转换对我来说不是一个选项,因为我试图避免前置*。

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)

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,
))

3 个解决方案

#1


json_encode converted your object accordingly to its properties' visibilities.

json_encode将您的对象相应地转换为其属性的可见性。

Since Tinyrocket\Magento\Objects\MagentoObjectCollection's $collection is a protected property, its value isn't read by json_encode.

由于Tinyrocket \ Magento \ Objects \ MagentoObjectCollection的$ collection是受保护的属性,因此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.

我有两个解决这个问题的方法,其中一个需要修改Magento的源代码,因此我不建议它,因为它可能会产生错误,或者每次更新CMS时都会中断。


The first solution uses Reflection, so you will need PHP 5, which shouldn't be a problem since Magento needs PHP 5.4.

第一个解决方案使用Reflection,所以你需要PHP 5,这应该不是问题,因为Magento需要PHP 5.4。

The following function loops through a \Tinyrocket\Magento\Objects\MagentoObjectCollection object to read all properties, and returns an array.

以下函数循环通过\ Tinyrocket \ Magento \ Objects \ MagentoObjectCollection对象来读取所有属性,并返回一个数组。

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:

PHP文档的链接:


The second solution uses JsonSerializable, so you will need PHP 5.4, which shouldn't be a problem neither.

第二个解决方案使用JsonSerializable,因此您将需要PHP 5.4,这不应该是一个问题。

Once the jsonSerialize method is implemented on a class which implements JsonSerializable, json_encode will encode the return value of jsonSerialize.

一旦在实现JsonSerializable的类上实现了jsonSerialize方法,json_encode将编码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:

因此,您可以修改Magento的核心,并使\ Tinyrocket \ Magento \ Objects \ MagentoObjectCollection和\ Tinyrocket \ Magento \ Objects \ MagentoObject类实现\ 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);
    }
}

Then you get your array by calling json_encode() / json_decode() as you did:

然后你通过调用json_encode()/ json_decode()得到你的数组:

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.

虽然这个解决方案可能有助于解决您的问题,但我不推荐它,因为它需要修改Magento的核心,这可能会破坏其他模块,并且在更新后不再工作。您应该创建自己的插件并使用第一个解决方案,这是最好的方法。


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,
  ),
)

#2


If you are sure that the $result object is not null, can you try

如果您确定$ result对象不为null,可以尝试

$array = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', json_encode($result)), true );

$ array = json_decode(preg_replace('/ [\ x00- \ x1F \ x80- \ xFF] /','',json_encode($ result)),true);

#3


We can tour the object with a for loop .. in , and create our associative array with data. An example:

我们可以使用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);

#1


json_encode converted your object accordingly to its properties' visibilities.

json_encode将您的对象相应地转换为其属性的可见性。

Since Tinyrocket\Magento\Objects\MagentoObjectCollection's $collection is a protected property, its value isn't read by json_encode.

由于Tinyrocket \ Magento \ Objects \ MagentoObjectCollection的$ collection是受保护的属性,因此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.

我有两个解决这个问题的方法,其中一个需要修改Magento的源代码,因此我不建议它,因为它可能会产生错误,或者每次更新CMS时都会中断。


The first solution uses Reflection, so you will need PHP 5, which shouldn't be a problem since Magento needs PHP 5.4.

第一个解决方案使用Reflection,所以你需要PHP 5,这应该不是问题,因为Magento需要PHP 5.4。

The following function loops through a \Tinyrocket\Magento\Objects\MagentoObjectCollection object to read all properties, and returns an array.

以下函数循环通过\ Tinyrocket \ Magento \ Objects \ MagentoObjectCollection对象来读取所有属性,并返回一个数组。

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:

PHP文档的链接:


The second solution uses JsonSerializable, so you will need PHP 5.4, which shouldn't be a problem neither.

第二个解决方案使用JsonSerializable,因此您将需要PHP 5.4,这不应该是一个问题。

Once the jsonSerialize method is implemented on a class which implements JsonSerializable, json_encode will encode the return value of jsonSerialize.

一旦在实现JsonSerializable的类上实现了jsonSerialize方法,json_encode将编码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:

因此,您可以修改Magento的核心,并使\ Tinyrocket \ Magento \ Objects \ MagentoObjectCollection和\ Tinyrocket \ Magento \ Objects \ MagentoObject类实现\ 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);
    }
}

Then you get your array by calling json_encode() / json_decode() as you did:

然后你通过调用json_encode()/ json_decode()得到你的数组:

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.

虽然这个解决方案可能有助于解决您的问题,但我不推荐它,因为它需要修改Magento的核心,这可能会破坏其他模块,并且在更新后不再工作。您应该创建自己的插件并使用第一个解决方案,这是最好的方法。


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,
  ),
)

#2


If you are sure that the $result object is not null, can you try

如果您确定$ result对象不为null,可以尝试

$array = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', json_encode($result)), true );

$ array = json_decode(preg_replace('/ [\ x00- \ x1F \ x80- \ xFF] /','',json_encode($ result)),true);

#3


We can tour the object with a for loop .. in , and create our associative array with data. An example:

我们可以使用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);