将多维数组数据应用于对象

时间:2016-06-19 13:58:07

标签: php arrays object recursion

对于给定的PHP对象(从CouchDB加载)$obj

class stdClass#1 (3) {
    public $_id =>
    string(10) "nochecksum"
    public $_rev =>
    string(34) "1-4f734a24465bf7ba2de316fe87ffa0c1"
    public $rooms =>
    class stdClass#2 (1) {
        public $kitchen =>
        class stdClass#3 (1) {
            public $ceilingFan =>
            bool(false)
        }
    }
}

对于给定的多维数据数组$arr,包含属性的更改或新值:

array(1) {
    'rooms' =>
    array(1) {
        'kitchen' =>
        array(1) {
            'needsCleaning' =>
            bool(true)
        }
    }
}

如何将$obj的属性设置为$arr的值?

对于单维数组,解决方案很简单:

foreach ($arr as $k=>$v) {
    $obj->{$k}=$v;
}

我尝试使用递归函数,但我不知道如何引用父代:

$obj = setObjectFromArray($obj, $arr);

function setObjectFromArray($obj, $arr, $tree=Array())
{
    foreach ($arr as $k=>$v) {
        if (is_array($v)) {
            $tree[]=$k;
            $obj = setObjectFromArray($obj, $v, $tree);
        } else {
            // Here $tree is Array('rooms','kitchen')
            // I want to set $obj->rooms->kitchen->{$k}
        }
    }
    return $obj;
}

我认为将对象属性的引用传递给递归函数可能会起作用 - 但是我不太了解是否足以做出有根据的猜测。任何帮助表示赞赏

2 个答案:

答案 0 :(得分:1)

你可以这样做:

function setObjectFromArray($obj, $arr) {
    foreach ($arr as $k => $v) {
        $obj->{$k} = is_array($v) ? setObjectFromArray($obj->{$k}, $v) : $v;
    }
    return $obj;
}

与代码的主要区别在于赋值给$obj->{$k}而不是$obj:这样就可以在递归树的每个级别重写(或创建)属性。

请注意,即使您调用此功能:

$result = setObjectFromArray($obj, $arr);

... $obj仍然会被修改并等于$result

答案 1 :(得分:0)

这个解决方案并不是完全明显的,可能会在某个地方失败但仍然是 - 它的json函数对:

$r = array(
    'rooms' => array(
        'kitchen' => array(
            'needsCleaning' => true
        )
    )
);

echo '<pre>',print_r(json_decode(json_encode($r))), '</pre>';

解释:您将数组编码为json-string,然后将此字符串解码为object。

也许您可以进一步扩展此代码。