2010-11-12 30 views
8

Tôi có một cấu trúc biểu diễn một biểu mẫu và tôi muốn lặp lại nó bằng cách sử dụng RecursiveIterator. Vấn đề là điều này chỉ trả về các câu hỏi cấp cao nhất. Tôi đang làm gì sai?PHP RecursiveIterator đi ngang qua

Tổng số các hình thức:

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]); 
    } 
} 

Câu hỏi:

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; 
    } 


} 

Iteration:

$form = Form::loadById(1); 

foreach($form as $question){ 
    echo $question->getCaption().'<br />'; 
} 

Trả lời

9

Để lặp qua một số RecursiveIterator, bạn phải quấn nó vào một số RecursiveIteratorIterator.

Xem một số ví dụ tại

Giá trị mặc định lặp đi lặp lại chế độ duy nhất là liệt kê lá. Nếu bạn cũng muốn các nút có chứa xuất hiện trong lần lặp lại, hãy vượt qua RecursiveIteratorIterator::SELF_FIRST làm đối số thứ hai cho hàm tạo của RecursiveIteratorIterator

2

Vâng, như bạn có thể nhìn thấy here

public RecursiveIterator RecursiveIterator::getChildren (void) 

Returns an iterator for the current iterator entry. 

phương thức sẽ trả về một đối tượng đang triển khai trình lặp. Phương thức của bạn trả về một mảng đơn giản.

đoán của tôi sẽ được trở lại một cái gì đó như:

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

Điều này là do bạn đang sử dụng một iterator đệ quy vì vậy nó dự kiến ​​sẽ có mỗi nút của cây cùng loại (một iterator)

+0

Vâng, bây giờ tôi có vấn đề này, nhưng vấn đề chỉ là các nút cấp cao nhất và tôi thực sự không ' Tôi biết phải làm gì. Tôi sẽ đăng toàn bộ mã. – cypher

+0

Ok, tôi đã đăng toàn bộ nội dung, hãy xem nó. – cypher