我正在努力更好地理解PHP中的迭代器。对于此测试,我想制作一个项目树,并使用不同的RecursiveIteratorIterator
模式列出它们。 :: SELF_FIRST和:: CHILD_FIRST模式正如我所期望的那样工作。但是,当我想列出叶子时,它不会。在实现中必须有一些东西,它不允许该模式正常工作,因为它什么都没打印出来。我的Obj::hasChildren()
方法有问题吗?
这是测试类:
class Obj implements \RecursiveIterator {
public $children = array();
private $position;
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function valid()
{
return isset($this->children[$this->position]);
}
public function next()
{
$this->position++;
}
public function current()
{
return $this->children[$this->position];
}
public function rewind()
{
$this->position = 0;
}
public function key()
{
return $this->position;
}
public function hasChildren()
{
return !empty($this->children[$this->position]);
}
public function getChildren()
{
return $this->children[$this->position];
}
public function __toString()
{
return $this->name;
}
}
这是测试:
use RecursiveIteratorIterator as RII;
$o1 = new Obj('Root');
$i1 = new Obj('Item 1');
$i12 = new Obj('Subitem 2');
$i1->children[] = new Obj('Subitem 1');
$i1->children[] = $i12;
$i12->children[] = new Obj('Subsubitem 1');
$i12->children[] = new Obj('Enough....');
$o1->children[] = $i1;
$o1->children[] = new Obj('Item 2');
$o1->children[] = new Obj('Item 3');
foreach (new RII($o1, RII::LEAVES_ONLY) as $o) {
echo "<br>" . $o;
}
答案 0 :(得分:2)
您所假设的是指向正确的方向,您的hasChildren()
方法存在问题。将其与valid()
和current()
方法进行比较,您可能已经看到总是返回true。
因为只要有current()
,hasChildren()
就会返回true:
public function current()
{
return $this->children[$this->position];
}
和
public function hasChildren()
{
return !empty($this->children[$this->position]);
}
相反,您想要测试当前元素是否包含子元素:
public function hasChildren()
{
return !empty($this->current()->children);
}
给你输出的细微差别:
Subitem 1
Subsubitem 1
Enough....
Item 2
Item 3
始终为TRUE
返回hasChildren()
,RecursiveIteratorIterator
无法检测到任何离开。根据树的概念,这是不可能的,但在遍历过程中 - 正如你用“bug”所证明的那样 - 显然可能:)
另见(如果可以的话):