多维数组转换为对象,具体方法

4

我知道这种类型的问题已经被问过很多次了,但我还没有找到我想要的解决方法。

所以,基本上我有这个数组。

array(7) {
  ["site"]=>
  array(5) {
    ["production"]=>
    bool(false)
    ["url"]=>
    string(29) "http://localhost/"
    ["name"]=>
    string(6) "Sitename"
    ["title"]=>
    string(7) ": Index"
    ["pagedata"]=>
    array(1) {
      ["default"]=>
      string(5) "Index"
    }
  }
  ["DB"]=>
  array(5) {
    ["host"]=>
    string(9) "localhost"
    ["user"]=>
    string(4) "root"
    ["pass"]=>
    string(4) "secret"
    ["database"]=>
    string(12) "database"
    ["engine"]=>
    string(7) "eMySQLi"
  }
  ["cache"]=>
  array(2) {
    ["file"]=>
    array(1) {
      ["time"]=>
      int(500)
    }
    ["memcache"]=>
    array(2) {
      ["my_first_vps_ip"]=>
      string(17) "my_first_vps_port"
      ["my_second_vps_ip"]=>
      string(18) "my_second_vps_port"
    }
  }
  ["skin"]=>
  array(2) {
    ["name"]=>
    string(9) "thehabbos"
    ["mobile"]=>
    array(2) {
      ["enabled"]=>
      bool(true)
      ["name"]=>
      string(16) "mobile_thehabbos"
    }
  }
  ["lang"]=>
  array(1) {
    ["name"]=>
    string(7) "English"
  }
  ["widget"]=>
  array(1) {
    ["default"]=>
    string(7) "Icecron"
  }
  ["cron"]=>
  array(1) {
    ["DatabaseBackup"]=>
    array(1) {
      ["execute_every"]=>
      int(86400)
    }
  }
}

所以,如果我使用这样的方法(将数组转换为对象)来“解析”此数组...
    private function parse($arr)
    {
        foreach ($arr as $key => $val) 
        {
            $this->{$key} = is_array($val) ? $this->parse($val) : $val;
        }
        return $this;
    }

我最终会得到类似以下的东西...
object(Configure)#3 (27) {
  ["production"]=>
  bool(false)
  ["url"]=>
  string(29) "http://localhost/RevFramework"
  ["name"]=>
  string(7) "English"
  ["title"]=>
  string(7) ": Index"
  ["default"]=>
  string(7) "Icecron"
  ["pagedata"]=>
  *RECURSION*
  ["site"]=>
  *RECURSION*
  ["host"]=>
  string(9) "localhost"
  ["user"]=>
  string(4) "root"
  ["pass"]=>
  string(4) "root"
  ["database"]=>
  string(12) "rev_database"
  ["engine"]=>
  string(7) "eMySQLi"
  ["DB"]=>
  *RECURSION*
  ["time"]=>
  int(500)
  ["file"]=>
  *RECURSION*
  ["my_first_vps_ip"]=>
  string(17) "my_first_vps_port"
  ["my_second_vps_ip"]=>
  string(18) "my_second_vps_port"
  ["memcache"]=>
  *RECURSION*
  ["cache"]=>
  *RECURSION*
  ["enabled"]=>
  bool(true)
  ["mobile"]=>
  *RECURSION*
  ["skin"]=>
  *RECURSION*
  ["lang"]=>
  *RECURSION*
  ["widget"]=>
  *RECURSION*
  ["execute_every"]=>
  int(86400)
  ["DatabaseBackup"]=>
  *RECURSION*
  ["cron"]=>
  *RECURSION*
}

因此,我可以像这样使用它...。
echo $this->url;

但是我想要做的是,像这样使用它...
echo $this->site->url;

有什么办法能够实现这个目标吗,如果有的话?
2个回答

6

您需要实例化一个新对象来设置数组值的属性。除非您有更具体的要求,否则使用stdClass即可:

private function parse(array $arr, stdClass $parent = null) {
    if ($parent === null) {
        $parent = $this;
    }

    foreach ($arr as $key => $val) {
        if (is_array($val)) {
            $parent->$key = $this->parse($val, new stdClass);
        } else {
            $parent->$key = $val;
        }
    }

    return $parent;
}

1
这是我准备的一个示例,展示了使用 stdClass 的两种不同方式:http://codepad.org/mkG1W320 - Jared Farrish
非常感谢!我会尝试并比较这两种方法,看看我会选择哪一种! - Manuel Fernández
1
@Manuel json_decode 隐式地创建了一个 stdClass 实例。如果你想要一个对象,那么这个对象需要是某个类的实例。在这种情况下,stdClass 是一个默认的“虚拟”类。JSON 方法是一个不错的技巧,但请注意它无法处理某些类型的变量(如资源),这些变量在编码/解码过程中会丢失。 - deceze
哦,我明白了,谢谢。不管怎样,现在它完美地工作了。再次感谢大家。 - Manuel Fernández

5
我想这会做你想要的事情:
$obj = json_decode(json_encode($my_array));
echo $obj->site->url;

正是我想要的,唯一的问题是我不能将它分配给 $this,但没关系。非常感谢! - Manuel Fernández

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