如何递归迭代对象?

时间:2016-12-06 12:38:20

标签: php object

我有这个类的实例,它包含这个类的几个实例的数组。并且每个都可以包含此类的实例等。此类实现树模型。

class Node implements Arrayable, Iterator, Jsonable, JsonSerializable, Countable, ArrayAccess 
{
    /**
     * @var Node[] 
     */
    protected $childs = [];

    public function childs()
    {
       return $this->childs;
    }

    /*
     * @var Node $node 
     */
    public function add(Node $node)
    {
       $this->childs[] = $node;
    }

    ...
       Here implementation of Interaces
    ...
}

我希望将来所有对象模型都作为json表示的数组结构。为此,我需要递归迭代所有对象strucutre。我可以用递归调用interate函数做简单的foreach函数,但我喜欢使用PHP Interator接口,它提供了这个功能。

我怎么做?

我尝试使用此代码,但它不起作用

//    $this->tree is istance of Node class 

$iterator = new RecursiveArrayIterator($this->tree);
$iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST );

foreach($this->tree as $key => $node) {

}

1 个答案:

答案 0 :(得分:1)

我仍然不太确定你要做什么,但这里有一些可能对你有帮助的例子( 下面的完整代码):

实施\JsonSerializable

实现此接口时,您将能够控制在类的任何实例上使用json_encode时将序列化的数据:

<?php
class Node implements \JsonSerializable
{
    // ...

    /**
     * @inheritdoc
     */
    public function jsonSerialize()
    {
        return [
            'data' => $this->data,
            'children' => $this->children
        ];
    }
}

// ...

print_r(json_encode($root, JSON_PRETTY_PRINT));

扩展\RecursiveArrayIterator

为此,您只需扩展\RecursiveArrayIterator并实施所需的方法即可使用Node类:

<?php
class NodeIterator extends \RecursiveArrayIterator
{
    /**
     * @inheritdoc
     */
    public function hasChildren()
    {
        return $this->current()->hasChildren();
    }

    /**
     * @inheritdoc
     */
    public function getChildren()
    {
        return new NodeIterator($this->current()->getChildren());
    }
}

// ...

$it = new RecursiveIteratorIterator(
    new NodeIterator([$root]),
    RecursiveIteratorIterator::SELF_FIRST
);

在实施\RecursiveArrayIterator时扩展\IteratorAggregate

对上述内容的扩展可能是在\IteratorAggregate

上实施Node
<?php
class Node implements \IteratorAggregate
{
    // ...

    /**
     * @inheritdoc
     */
    public function getIterator()
    {
        return new NodeIterator([$this]);
    }
}

// ...

$it = new RecursiveIteratorIterator($root, RecursiveIteratorIterator::SELF_FIRST);

演示https://3v4l.org/D0GfX