如何将一个对象转换为数组?

209
<?php
   print_r($response->response->docs);
?>

输出如下:

    Array 
(
    [0] => Object 
            (
                [_fields:private] => Array 
                                    (
                                        [id]=>9093 
                                        [name]=>zahir
                                    ) 
            Object 
            ( 
                [_fields:private] => Array 
                                    (
                                        [id]=>9094 
                                        [name]=>hussain
                                    )..
            )
)

我该如何将这个对象转换成数组?我希望输出以下内容:

Array
(
    [0]=>
    (
        [id]=>9093 
        [name]=>zahir
    ) 
    [1]=>
    (
        [id]=>9094 
        [name]=>hussain
    )...
)

这可行吗?

11个回答

393

一维数组

对于转换单维数组,您可以使用 (array) 进行强制类型转换,或者使用 get_object_vars 函数,这个函数在 Benoit 的回答 中提到过。

// Cast to an array
$array = (array) $object;
// get_object_vars
$array = get_object_vars($object);

它们之间的工作方式略有不同。例如,get_object_vars将返回一个数组,其中仅包含公开可访问属性,除非它是从您正在传递的对象的作用域内调用的(即在对象的成员函数中)。另一方面,(array)会转换为一个数组,并保留了数组中所有公共、私有和受保护的成员,尽管现在都是公共的。

多维数组

一种有点“肮脏”的方法是使用PHP >= 5.2的原生JSON函数将其编码为JSON,然后解码回数组。但是,这不包括私有和受保护的成员,并且不适用于包含无法进行JSON编码的数据(如二进制数据)的对象。

// The second parameter of json_decode forces parsing into an associative array
$array = json_decode(json_encode($object), true);

或者,以下功能将从对象转换为包括私有和受保护成员的数组,取自这里并修改使用强制类型转换:

function objectToArray ($object) {
    if(!is_object($object) && !is_array($object))
        return $object;

    return array_map('objectToArray', (array) $object);
}

5
第一种解决方案无法处理多维度,但是第二种解决方案效果很好。 - sbuck
1
第二个解决方案提醒我,json_decode() 有第二个参数,我忘了...谢谢。 - Tyler
1
我想知道为什么这个答案得到了这么多票。两种解决方案都不如get_object_vars清晰和美观。 - RJD22
3
@RJD22: 我已经更新了我的回答,使其更像是一个“事实上”的资源,希望你现在认为它值得被点赞。;-) 提醒其他人这里评论所提到的“第二个解决方案”是JSON方案,也就是我的第一个答案中的第二个解决方案。 - Andy E
太棒了!我被这个解决方案惊艳到了,一直往下滚才找到它! - eozzy
@RJD22 get_object_vars 不会包括私有成员,而强制转换为数组将会(带有奇怪的类前缀)。根据您的用例,它们并不等同。 - Saeven

137

你应该查看get_object_vars,由于你的属性是声明为私有的,因此你应该在类内部调用它并返回其结果。

请注意,对于像字符串这样的原始数据类型,它将工作得很好,但我不知道它在嵌套对象方面的行为如何。

在你的情况下,你需要做类似下面这样的事情:

<?php
   print_r(get_object_vars($response->response->docs));
?>

45

你可以依靠JSON编码/解码函数的行为,快速将深层嵌套的对象转换为关联数组:

$array = json_decode(json_encode($response->response->docs), true);

2
这是解决这个问题最简单的答案。使用它,效果非常棒。谢谢。 - Dustin Fraker
7
请注意 - 如果您的数组包含UTF8有效数据,则此操作将起作用。如果您的数组包含其他编码,比如Win1250,它将失败,因为json_encode会失败(php 5.3)。 - Radek
如何将其转换回对象? - Peyman Mohamadpour
@Trix 再次使用 JSON,即json_decode(json_encode($array), FALSE)。这个方法会(递归地)将所有子数组转换为对象。 - Mufaddal
@galdikas 当然可以。正如您所看到的,json_encode() (PHP 5 >= 5.2.0, PECL json >= 1.2.0, PHP 7)json_decode() (PHP 5 >= 5.2.0, PECL json >= 1.2.0, PHP 7) 在PHP7中都被支持。 - Axel
显示剩余3条评论

34

小心:

$array = (array) $object;

进行浅层次转换($object->innerObject = new stdClass()仍然是一个对象),然后使用json来回转换虽然可行,但如果性能成为问题,则不是一个好的选择。

如果您需要将所有对象转换为关联数组,这里有一种更好的方法可以实现(从我记不清楚的哪里抓取的代码):

function toArray($obj)
{
    if (is_object($obj)) $obj = (array)$obj;
    if (is_array($obj)) {
        $new = array();
        foreach ($obj as $key => $val) {
            $new[$key] = toArray($val);
        }
    } else {
        $new = $obj;
    }

    return $new;
}

我无法读取对象转换后的数组:http://codepad.viper-7.com/AkX5pq 你有任何关于这个的解释吗? - Damien
1
我最喜欢这个答案。Andy E的递归函数本质上做了同样的事情,但我发现这个更容易理解。 - HartleySan

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

我尝试了几种方法来对一个对象进行foreach,但是这确实是我见过最简单和酷的解决方法。只需要一行代码 :)


它只能完美地处理公共对象属性,而不考虑私有属性。 - Limon
这里有一些关于使用JsonSerialize函数的解释,但它不是一行解决方案,我读到了这不是一个好的做法 :( https://dev59.com/IGw05IYBdhLWcg3w0VKa。感谢您的建议。 - m3nda
如何将其转换回对象? - Peyman Mohamadpour

18

简化版:

$arrayObject = new ArrayObject($object);
$array = $arrayObject->getArrayCopy();

更新后的递归版本:

class RecursiveArrayObject extends ArrayObject
{
    function getArrayCopy()
    {
        $resultArray = parent::getArrayCopy();
        foreach($resultArray as $key => $val) {
            if (!is_object($val)) {
                continue;
            }
            $o = new RecursiveArrayObject($val);
            $resultArray[$key] = $o->getArrayCopy();
        }
        return $resultArray;
    }
}

$arrayObject = new RecursiveArrayObject($object);
$array = $arrayObject->getArrayCopy();

2

试试这个:

 <?php
  print_r(json_decode(json_encode($response->response->docs),true));
 ?>

2

我曾经遇到同样的问题,并使用上面提到的 get_object_vars 方法解决了问题。

此外,我还需要使用 json_decode 方法将对象转换为数组,并使用传统的“for”循环(而不是 for-each 循环)来迭代该数组。


0

我在使用Andy Earnshaw的答案时遇到了问题,因为我已经将这个函数分解到我的应用程序中的一个单独的类“HelperFunctions”中,这意味着对objectToArray()的递归调用失败了。

我通过在array_map调用中指定类名来克服了这个问题,如下所示:

public function objectToArray($object) {
    if (!is_object($object) && !is_array($object))
        return $object;
    return array_map(array("HelperFunctions", "objectToArray"), (array) $object);
}

我本想在评论中写这个问题,但是我的声望还不够。


-1

你也可以使用 PHP 的 array_values() 方法


4
不行。“array_values() 期望参数1为数组,但传递了一个对象。” - manatwork

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接