我正在集成一个API到我的网站,它与存储在对象中的数据一起工作,而我的代码是使用数组编写的。

我想要一个快速和肮脏的函数将对象转换为数组。


当前回答

我使用这个(需要递归解决适当的关键字):

    /**
     * This method returns the array corresponding to an object, including non public members.
     *
     * If the deep flag is true, is will operate recursively, otherwise (if false) just at the first level.
     *
     * @param object $obj
     * @param bool $deep = true
     * @return array
     * @throws \Exception
     */
    public static function objectToArray(object $obj, bool $deep = true)
    {
        $reflectionClass = new \ReflectionClass(get_class($obj));
        $array = [];
        foreach ($reflectionClass->getProperties() as $property) {
            $property->setAccessible(true);
            $val = $property->getValue($obj);
            if (true === $deep && is_object($val)) {
                $val = self::objectToArray($val);
            }
            $array[$property->getName()] = $val;
            $property->setAccessible(false);
        }
        return $array;
    }

用法示例,代码如下:

class AA{
    public $bb = null;
    protected $one = 11;

}

class BB{
    protected $two = 22;
}


$a = new AA();
$b = new BB();
$a->bb = $b;

var_dump($a)

将打印这个:

array(2) {
  ["bb"] => array(1) {
    ["two"] => int(22)
  }
  ["one"] => int(11)
}

其他回答

当你从数据库中以对象的形式获取数据时,你可能想这样做:

// Suppose 'result' is the end product from some query $query

$result = $mysqli->query($query);
$result = db_result_to_array($result);

function db_result_to_array($result)
{
    $res_array = array();

    for ($count=0; $row = $result->fetch_assoc(); $count++)
        $res_array[$count] = $row;

    return $res_array;
}

@SpYk3HH的简短解决方案

function objectToArray($o)
{
    $a = array();
    foreach ($o as $k => $v)
        $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v;

    return $a;
}

首先,如果你需要一个来自对象的数组,你可能应该首先将数据构成一个数组。想想看。

不要使用foreach语句或JSON转换。如果您计划这样做,同样是在处理数据结构,而不是对象。

如果你真的需要它,可以使用面向对象的方法来获得干净和可维护的代码。例如:

对象作为数组

class PersonArray implements \ArrayAccess, \IteratorAggregate
{
    public function __construct(Person $person) {
        $this->person = $person;
    }
    // ...
 }

如果你需要所有的属性,使用一个传输对象:

class PersonTransferObject
{
    private $person;

    public function __construct(Person $person) {
        $this->person = $person;
    }

    public function toArray() {
        return [
            // 'name' => $this->person->getName();
        ];
    }

 }

由于很多人发现这个问题是因为在动态访问对象属性时遇到了麻烦,我只想指出,你可以在PHP中这样做:

在上下文(删除HTML输出可读性):

$valueRows = json_decode("{...}"); // Rows of unordered values decoded from a JSON object

foreach ($valueRows as $valueRow) {

    foreach ($references as $reference) {

        if (isset($valueRow->{$reference->valueName})) {
            $tableHtml .= $valueRow->{$reference->valueName};
        }
        else {
            $tableHtml .= " ";
        }
    }
}
class Test{
    const A = 1;
    public $b = 'two';
    private $c = test::A;

    public function __toArray(){
        return call_user_func('get_object_vars', $this);
    }
}

$my_test = new Test();
var_dump((array)$my_test);
var_dump($my_test->__toArray());

输出

array(2) {
    ["b"]=>
    string(3) "two"
    ["Testc"]=>
    int(1)
}
array(1) {
    ["b"]=>
    string(3) "two"
}