web 中 bbs 例子(多次递归)

数据库设计:
create table `header`(  // 父表
  parent int not null, //父级
  poster varchar(20) not null, //作者
  posted datetime,            //时间
  title varchar(100),        //标题    
  children tiny(1) default 0, //是否有回复(1)[YES] (0)[NO]
  postid int not null primary key // 主键
);

create table `body`( //具体内容
  postid int not null primary key,
  text text
);


代码示例(省略头尾,只显示大概内容区):
<?php
/*
 * expand_all()      全部展示    
 * $expanded         标示那些已经展开的
 * $expand           那些要被展开
 * $_GET['expand']   表示那些是要被展示的
 * $_GET['collapse'] 表示那些是要折叠的
*/

session_start();

function db_connect(){
  $conn = new mysqli("localhost", "root", "123456", "dbname");
  $conn->query("set names utf8");
  return $conn
}
// 全部要展示出来
function expand_all(&$expanded){
  $sql = "select postid from header where children = 1";
  $conn = db_connect();
  $result = $conn->query($sql);
  while($row = $result->fetch_assoc()){
    $expanded[$row['postid']] = true;
  }
}

// 调用函数 start开始的parent, $row 标示行号,用于交替颜色
function display_tree($expanded, $row = 0, $start = 0){
  echo "<table width='580'>\n";
  $tree = new treenode($start, 1, true, -1, $expanded);
  $tree->display($row);
  echo "</table>\n";
}
if(!isset($_GET['expand'])){
  $_SESSION['expanded'] = array();
}

// 那些是要显示出来的
if(isset($_GET['expand'])){
  if($_GET['expand'] == 'all'){
    expand_all($_SESSION['expanded']);
  }else{
    $_SESSION[$_GET['expanded']] = true;    
  }
}

// 那些是要折叠
if(isset($_GET['collaspe'])){
  if($_GET['collaspe'] == 'all'){
   $_SESSION['expanded'] = array();
  }else{
   unset($_SESSION[$_GET['collapse']]);
  }
}
// class
class treenode {
  public $m_postid;      // id
  public $m_children;    // 是否有回复
  public $m_depth;      // 深度,就是递归深入的深度
  public $m_childlist; // 是一个数组,表示要展示的 id

  function __construct($postid, $children, $expand, $depth, $expanded){
   $this->m_postid = $postid;
   $this->m_children = $chilren;
   $this->m_depth = $depth;
   $this->m_childlist = array();

   if($expand && $this->m_children){
    $conn = db_connect();
    $query = "select * from header where parent = '" . $this->postid .  "' order by posted";
    $result = $conn->query($query);
    for($count=0; $row = $conn->fetch_assoc(); $count++){
      if($expanded[$row['postid']] == true){
       $expand = true;
      }else{
       $expand = false;
      }
      $this->m_childlist[$count] = new treenode($row['postid'], $row['children'],$expand, $depth+1, $expanded);
    }
   }
  }

  function display($row){
    if($this->depth>-1){
      echo "<tr><td bgcolor=\"";
      if($row%2){
    echo "#cccccc\">";
      }else{
        echo "#ffffff\">"
      }
      // 缩进
      for($i=0; $i<$this->depth; $i++){
    echo "&nbsp;&nbspp;";
      }
      if($this->children && sizeof($this->m_childlist)){
    echo "<a href=\"index.php?collapse=\"" . $this->postid . "\"><img src=\"images/--.gif\"/></a>";
      }else if($this->children){
    echo "<a href=\"index.php?expand=\"" . $this->postid . "\"><img src=\"images/++.gif\"/></a>";
      }else{
    echo "&nbsp;&nbsp;";
      }
      echo "<a href=\"view.php?parent={$this->postid}\">" . $this->postid ."</a></td></tr>\n";
      $row++;
    }
    $num_children = sizeof($this->m_childlist);
    for($i=0; $i<$num_children; $i++){
      $row = $this->m_childlist[$i]->display($row);
    }
    return $row;
  }

}
// 最后调用
display_tree($_SESSION['expanded']);
?>

图片效果如下:

首页初始化时如下:

全部展开时如下

以下是部分展开的两个效果图:

 

posted @ 2014-02-10 21:31  好记性还真不如烂笔头  阅读(434)  评论(0编辑  收藏  举报