使用PHP的RecursiveIteratorIterator迭代多维数组

3
我需要缓存一棵树状结构并在以后访问它。问题是:我真的不知道如何声明数据,使其适合于RecursiveIteratorIterator等。这可能是一个非常新手的问题,但我已经尝试了很多组合,想不出更好的办法 :-(
从概念上来看,数据长这样:
ROOT code : 1111, label : Universe
   - code : 2000, label : Asia
      - code : 3203, label : Hongkong
           -code : 2081, label: Greater Area
           -code : 2041, label: Downtown
      - code : 4020, label : Shanghai
   - code : 6201, label : Africa
   - code : 321, label : North America

我想访问给定代码的所有直接子级,例如对于亚洲的香港和上海。 RecursiveIteratorIterator似乎可以轻松实现此功能。

// looking for Asia with code = 2000
$iterator = new RecursiveIteratorIterator(new Universe_Tree($tree));
foreach ($iterator as $key => $item) {
       if ($item->code == 2000) {
            var_dump($iterator->callGetChildren());

       }
}

目前,类Universe_Tree还没有太多作用:

class Universe_Tree extends ArrayIterator implements RecursiveIterator  {

    public function hasChildren() {
        return (is_array($this->current()));
    }

    public function getChildren() {
        return new self($this->current());
    }

}

我的最佳方法是创建每个节点的对象并将它们存储在一个嵌套数组中。

$universe = new stdClass();
$universe ->code = 1111;
$universe ->label = "Universe"; 

$tree = array(
  array($universe,
    array(
       $asia,
      (array($shanghai,$hongkong)),
       $europe
        // and so on
       )
      );

很不幸,$iterator->callGetChildren()并没有返回子元素,只返回了当前元素。可能是因为节点没有正确地嵌套在一起。我还尝试使用带有parentId的数组进行嵌套,但是这导致了来自ArrayIterator的错误消息,说这不是一个数组或对象,尽管根据var_dump,它确实是一个数组。我还能尝试什么?


1
你看过这个帖子了吗? - bobthyasian
2
我想看看你实际使用的树,但是这里有一些指针:(1)使用ArrayObject(或实际数组)而不是stdClass可能会更有帮助;(2)默认情况下,RecursiveIteratorIteratorLEAVES_ONLY,只显示标量。将RecursiveIteratorIterator::SELF_FIRSTRecursiveIteratorIterator::CHILD_FIRST作为第二个参数传递给RecursiveIteratorIterator - Wrikken
谢谢,伙计们。我尝试了使用ArrayObject,并且重新检查了其他在stackoverflow问题中提到的选项,但都没有成功。最终,我放弃了并采用了另一种使用SimpleXML的解决方案。 - herrjeh42
1个回答

0

这是一种答案。实际上,我放弃了,并采用了基于SimpleXML的解决方案。非常简单,代码很少。最终,有人会遇到这个问题,我的“解决方案”也可能成为他的一种方式。所以我在这里包含它:

// data represented as xml
$xmlstring = <<<XML
<orgtree>
  <level number="1">
        <unit label="Universe" code="1111">
            <level number="2">
                <unit label="Asia" code="2000"></unit>
                    <level number="3">
                        <unit label="Hongkong" code="3203"></unit>
                           <level number="4">
                               <unit label="Greater Area" code="2081"></unit>
                               <unit label="Downtown" code="2041"></unit>
                           </level>
                    </level>
                </unit>
            <unit label="Africa" code="6201"></unit>
            <unit label="North America" code="321"></unit>
            </level>
        </unit>
    </level>
</orgtree>
XML;


   $xml = simplexml_load_string($xmlstring);
   // use xpath to select part of xml
   foreach ($xml->xpath('//unit[@code="2000"]') as $parentUnit)
   {
        $subtree = $parentUnit->level;
        foreach ($subtree->unit as $unit) {
                 var_dump($unit["label"]);
        }
   }

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