【问题标题】:implementing multi-level "iterator" in PHP在 PHP 中实现多级“迭代器”
【发布时间】:2011-07-04 12:16:00
【问题描述】:

我正在尝试为 cmets 列表创建一个类似 this one 的迭代器:

// the iterator class, pretty much the same as the one from the php docs...
abstract class MyIterator implements Iterator{

  public $position = 0,
         $list;

  public function __construct($list) {
    $this->list = $list;
    $this->position = 0;
  }

  public function rewind() {
    $this->position = 0;
  }

  public function current() {
    return $this->list[$this->position];
  }

  public function key() {
    return $this->position;
  }

  public function next() {
    ++$this->position;
  }

  public function valid() {
    return isset($this->list[$this->position]);
  }
}

评论迭代器:

class MyCommentIterator extends MyIterator{

  public function current(){
    return new Comment($this->list[$this->position]);
  }    
}

这就是我使用它的方式:

$comments = GetComments(); // gets the comments from the db
if($comments): ?>

  <ol>
    <?php foreach(new MyCommentIterator($comments) as $comment): ?>
    <li>
      <p class="author"><?php echo $comment->author(); ?></p>

      <div class="content">
        <?php echo $comment->content(); ?>
      </div>

      <!-- check for child comments and display them -->

    </li>
    <?php endforeach; ?>
  </ol>

<?php endif; ?>

所以一切正常,除了一件事:我不知道如何处理嵌套的 cmets :(

$comments 数组返回一个平面的 cmets 列表,例如:

[0] => object(
    'id' => 346,
    'parent' => 0,  // top level comment
    'author' => 'John',
    'content' => 'bla bla'         
  ),

[1] => object(
    'id' => 478,
    'parent' => 346,  // child comment of the comment with id =346
    'author' => 'John',
    'content' => 'bla bla'         
  )
...

我需要能够以某种方式检查子 cmets(在多个级别上)并将它们插入到其父 cmets 的 &lt;/li&gt; 之前...

有什么想法吗?

【问题讨论】:

    标签: php oop class iterator nested-loops


    【解决方案1】:

    递归是你的朋友。

    displaycomment(comment):
        $html .= "<ol>" . comment->html;
        foreach comment->child:
            $html .= "<li>" . displaycomment(child) . "</li>";
        $html .= "</ol>";
        return $html;
    

    本文中出现的所有代码都是伪代码。与真实代码的任何相似之处,无论工作正常还是损坏,纯属巧合。

    【讨论】:

      【解决方案2】:

      您可能想查看RecursiveIterator Interface PHP Manual。如果您使用该接口的方法扩展您的迭代器,您就可以使用 RecursiveIteratorIterator PHP Manual 的实例依次迭代您的 cmets。

      但是,由于您的输出是一个平面列表,您需要自己处理关卡的逻辑,例如向上插入&lt;ol&gt;,向下插入&lt;/ol&gt;

      使用标志来控制遍历子项的顺序。

      【讨论】:

        【解决方案3】:

        您使用的是平面数组,但实际上,该数组的项是树或分层数据结构。

        您基本上是在显示一个顺序列表。也许你应该先构造一个树形/分层数据结构,不显示,然后再显示树形列表中的数据。

        /* array */ function FlatArrayToTreeArray(/* array */ $MyFlatArray)
        {
          ...
        }
        
        /* void */ function IterateTree(/* array */ $MyTreeArray)
        {
          ...
        }
        
        /* void */ function Example() {
          $MyFlatArray = Array(
          0 => object(
              'id' => 346,
              'parent' => 0,  // top level comment
              'author' => 'John',
              'title' => 'Your restaurant food its too spicy',
              'content' => 'bla bla'         
            ),
          1 => object(
              'id' => 478,
              'parent' => 346,  // child comment of the comment with id =346
              'author' => 'Mike',
              'title' => 'Re: Your restaurant food its too spicy',
              'content' => 'bla bla'         
            ),  
          2 => object(
              'id' => 479,
              'parent' => 478,  // child comment of the comment with id =346
              'author' => 'John',
              'title' => 'Re: Your restaurant food its too spicy',
              'content' => 'bla bla'         
            ),  
          3 => object(
              'id' => 479,
              'parent' => 346,  // child comment of the comment with id =346
              'author' => 'Jane',
              'title' => 'Re: Your restaurant food its too spicy',
              'content' => 'bla bla'         
            )
          );
        
          $MyTreeArray = FlatArrayToTreeArray($myflatarray);
        
          IterateTree($MyTreeArray);
        } // function Example()
        

        干杯。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-11-09
          • 1970-01-01
          • 2018-10-06
          • 2016-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多