I have instance of this class, which contains an array of several instances of this class. And each of which can contain instances of this class, etc. This class implements the tree model.
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 ... }
I want get all objects model as array structure for JSON representation in future. For that I need recursive iterate all object structure. I can do it simple foreach function with recursive call interate function, but I like to use PHP Interator interfaces, which provides this functional.
How I can do it?
I tried this code, but it didn’t work:
// $this->tree is instance of Node class $iterator = new RecursiveArrayIterator($this->tree); $iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST ); foreach($this->tree as $key => $node) { }
Advertisement
Answer
I’m still not quite sure what you’re trying to do, but here are some examples which might help you (full code below):
Implementing JsonSerializable
:
When implementing this interface you’ll be able to control what data will be serialized when json_encode
is used on any instance of the class:
<?php class Node implements JsonSerializable { // ... /** * @inheritdoc */ public function jsonSerialize() { return [ 'data' => $this->data, 'children' => $this->children ]; } } // ... print_r(json_encode($root, JSON_PRETTY_PRINT));
Extending RecursiveArrayIterator
:
For this to work you only need to extend RecursiveArrayIterator
and implement the required methods to work with your Node
class:
<?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 );
Extending RecursiveArrayIterator
while implementing IteratorAggregate
:
An extension to the above could be to also implement IteratorAggregate
on Node
<?php class Node implements IteratorAggregate { // ... /** * @inheritdoc */ public function getIterator() { return new NodeIterator([$this]); } } // ... $it = new RecursiveIteratorIterator($root, RecursiveIteratorIterator::SELF_FIRST);
Demo: https://3v4l.org/D0GfX