代码之家  ›  专栏  ›  技术社区  ›  cypher

PHP递归迭代器遍历

  •  8
  • cypher  · 技术社区  · 14 年前

    问题是这只返回顶级问题。我做错什么了?

    整体形式:

    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->type, $question->caption, $question->other_text, $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 />';  
    }
    
    2 回复  |  直到 11 年前
        1
  •  9
  •   Gordon Haim Evgi    14 年前

    迭代 RecursiveIterator ,你必须把它包装成 RecursiveIteratorIterator .

    默认的迭代模式是只列出叶子。如果还希望包含的节点出现在迭代中,请通过 RecursiveIteratorIterator::SELF_FIRST 作为

        2
  •  2
  •   dierre    14 年前

    好吧,如你所见 here

    public RecursiveIterator RecursiveIterator::getChildren ( void )
    
    Returns an iterator for the current iterator entry. 
    

    方法应返回实现迭代器的对象。方法返回一个简单数组。

    我的猜测是返回如下内容:

    public function getChildren(){
        return new Question($this->subquestions);
    }
    

    这是因为您使用的是递归迭代器,因此预期树的每个节点都具有相同的类型(迭代器)