<?php
error_reporting(-1);
header('Content-Type: text/plain; charset="utf-8"');
class NodeIterator extends \RecursiveArrayIterator
{
/**
* @inheritdoc
*/
public function hasChildren()
{
return $this->current()->hasChildren();
}
/**
* @inheritdoc
*/
public function getChildren()
{
return new NodeIterator($this->current()->getChildren());
}
}
class Node implements \JsonSerializable, \IteratorAggregate
{
/**
* @var mixed
*/
private $data;
/**
* @var Node[]
*/
private $children = [];
/**
* Node constructor.
*
* @param mixed $data
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* @return mixed
*/
public function getData()
{
return $this->data;
}
/**
* @return bool
*/
public function hasChildren()
{
return count($this->children) > 0;
}
/**
* @return \RecursiveArrayIterator
*/
public function getChildren()
{
return new \RecursiveArrayIterator($this->children);
}
/**
* @param Node $child
*
* @return Node
*/
public function addChild(self $child)
{
if (in_array($child, $this->children, true)) {
throw new \InvalidArgumentException('duplicate');
}
$this->children[] = $child;
return $child;
}
/**
* @inheritdoc
*/
public function jsonSerialize()
{
return [
'data' => $this->data,
'children' => $this->children
];
}
/**
* @inheritdoc
*/
public function getIterator()
{
return new NodeIterator([$this]);
}
}
$root = new Node('root');
$root->addChild(new Node('sub1'))->addChild(new Node('sub1.1'));
$root->addChild(new Node('sub2'))->addChild(new Node('sub2.1'))->addChild(new Node('sub.2.1.1'));
$root->addChild(new Node('sub3'));
print_r(json_encode($root, JSON_PRETTY_PRINT));
echo "\n\n";
foreach ($it = new RecursiveIteratorIterator(new NodeIterator([$root]), RecursiveIteratorIterator::SELF_FIRST) as $node) {
echo str_repeat('.', $it->getDepth()), $node->getData(), "\n";
}
echo "\n\n";
foreach ($it = new RecursiveIteratorIterator($root, RecursiveIteratorIterator::SELF_FIRST) as $node) {
echo str_repeat('.', $it->getDepth()), $node->getData(), "\n";
}
preferences:
26.14 ms | 410 KiB | 5 Q