我有一个表示表单的结构,我想使用RecursiveIterator迭代它.
问题是这只会返回顶级问题.我究竟做错了什么?
问题是这只会返回顶级问题.我究竟做错了什么?
整体形式:
class Form implements RecursiveIterator{ private $id; private $caption; private $other_text; private $questions = array(); private $current; private function __construct(DibiRow $row){ $this->id = $row->id; $this->caption = $row->caption; $this->other_text = $row->other_text; $this->loadQuestions(); } private function loadQuestions(){ $questions = dibi::query('SELECT * FROM cyp_questions WHERE form_id = %i AND parent_id IS NULL',$this->id); while($question = $questions->fetch()) $this->questions[] = new Question($question->question_id,$question->type,$question->caption,$question->other_text,$question->triggers_unique == 1); } /** * @throws InvalidArgumentException * @param $id * @return Form */ public static function loadById($id){ $form = dibi::query('SELECT * FROM cyp_forms WHERE id = %i',$id)->fetch(); if($form === false) throw new InvalidArgumentException('Form with id '.$id.' was not found.'); return new Form($form); } /** * @throws FormFieldException * @return bool */ public function validate($postfields){ } public function getQuestions(){ return $this->questions; } public function getChildren(){ return $this->questions[$this->current]; } public function hasChildren(){ return count($this->questions) > 0; } public function current(){ return $this->questions[$this->current]; } public function key(){ return $this->current; } public function next(){ $this->current++; } public function rewind(){ $this->current = 0; } public function valid(){ return isset($this->questions[$this->current]); } }
题:
class Question implements RecursiveIterator{ private $id; private $type; private $answers = array(); private $subquestions = array(); private $other_text; private $triggers_unique; private $caption; private $current = 0; public function __construct($id,$type,$caption,$other_text = null,$triggers_unique = false){ $this->id = $id; $this->type = $type; $this->caption = $caption; $this->other_text = $other_text; $this->triggers_unique = $triggers_unique; $this->setSubQuestions(); } private function setSubQuestions(){ $questions = dibi::query('SELECT * FROM cyp_questions WHERE parent_id = %i',$this->id); while($question = $questions->fetch()) $this->subquestions[] = new Question($question->question_id,$question->triggers_unique == 1); } public function getOtherText(){ return $this->other_text; } public function getCaption(){ return $this->caption; } public function addAnswer($answer){ $this->answers[] = $answer; } public function getChildren(){ return $this->subquestions[$this->current]; } public function hasChildren(){ return count($this->subquestions) > 0; } public function current(){ return $this->subquestions[$this->current]; } public function key(){ return $this->id; } public function next(){ ++$this->current; } public function rewind(){ $this->current = 0; } public function valid(){ return isset($this->subquestions[$this->current]); } public function getAnswers(){ return $this->answers; } }
迭代:
$form = Form::loadById(1); foreach($form as $question){ echo $question->getCaption().'<br />'; }
要遍历RecursiveIterator,必须将其包装到RecursiveIteratorIterator中.
看一些例子
> Introduction to Spl
> SplWiki
默认迭代模式仅用于列出叶子.如果您还希望包含节点出现在迭代中,请将RecursiveIteratorIterator :: SELF_FIRST作为第二个参数传递给RecursiveIteratorIterator的构造函数