数据库设计:
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']);
?>

图片效果如下:

首页初始化时如下:

全部展开时如下

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

web 中 bbs 例子(多次递归)的更多相关文章

  1. HT for Web中3D流动效果的实现与应用

    流动效果在3D领域有着广泛的应用场景,如上图中医学领域可通过3D的流动直观的观察人体血液的流动,燃气领域可用于监控管道内流动的液体或气体的流向.流速和温度等指标. 如今企业数据中心机房普遍面临着设备散 ...

  2. 基于gSOAP使用头文件的C语言版web service开发过程例子

    基于gSOAP使用头文件的C语言版web service开发过程例子 一服务端 1 打开VS2005,创建一个工程,命名为calcServer. 2 添加一个头文件calc.h,编辑内容如下: 1// ...

  3. 【spring实战第五版遇到的坑】3.1中的例子报错

    按照书中的例子,一直做到第3.1章使用JDBC读写数据时,在提交设计的taco表单时,报了如下的异常信息: Failed to convert property value of type java. ...

  4. Web中的积累:外观模式 Facade

    摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 壹 前言 目测好久没写文章了,距离上一篇文章也有二十多天.我是怎么了?哈 ...

  5. Html的本质及在web中的作用

    概要 本文以一个Socket程序为例由浅及深地揭示了Html的本质问题,同时介绍了作为web开发者我们在开发网站时需要做的事情 Html的本质以及开发需要的工作 1.服务器-客户端模型 其实,对于所有 ...

  6. [翻译]Spring MVC RESTFul Web Service CRUD 例子

    Spring MVC RESTFul Web Service CRUD 例子 本文主要翻译自:http://memorynotfound.com/spring-mvc-restful-web-serv ...

  7. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

  8. java web中各种context的关系

    我举得这篇文章解决了我的很多疑惑,理清了我以前不太清楚的Context关系,读懂这篇文章很有助于理解源码, 原文链接在这里:https://www.jianshu.com/p/2537e2fec546 ...

  9. 优化Web中的性能

    优化Web中的性能 简介 web的优化就是一场阻止http请求最终访问到数据库的战争. 优化的方式就是加缓存,在各个节点加缓存. web请求的流程及节点 熟悉流程及节点,才能定位性能的问题.而且优化的 ...

随机推荐

  1. SQLite 入门教程(二)创建、修改、删除表 (转)

    转于 SQLite 入门教程(二)创建.修改.删除表 一.数据库定义语言 DDL 在关系型数据库中,数据库中的表 Table.视图 View.索引 Index.关系 Relationship 和触发器 ...

  2. iOS 静态库和动态库

    这两个东西都是编译好的二进制文件.就是用法不同而已.为什么要分为动态和静态两种库呢?先看下图:

  3. python学习(3)

    Python学习(3)切片(Slice):根据索引范围取出字符串里面的内容,比如: l=range(100)   l[:8] [0, 1, 2, 3, 4, 5, 6, 7]              ...

  4. SecureCRT 终端仿真程序 v7.0.0.326 中文绿色便携破解版

    http://wd.jb51.net:81/201205/tools/SecureCRT_jb51.rar Secure CRT是一款支持 SSH2.SSH1.Telnet.Telnet/SSH.Re ...

  5. [Javascript] Drawing Paths - Lines and Rectangles

    <!DOCTYPE html> <html> <head> <meta name="description" content=" ...

  6. SecureCRT恢复默认字体

    1\要想永久的改变的就跟我来吧,选项--全局选项--常规--默认会话--编辑默认设置--外观--当前颜色方案--选择自己喜欢的方案就行啦,然后选择保存就OK啦方案二: 自从装了Win7之后,觉得sec ...

  7. 使用摘要流获取文件的MD5

    摘要流是过滤流的一种,使用它可以再读取和写入流时获取流的摘要信息(MD5/SHA). 使用摘要流包装流时,需要额外传递一个MessageDigest对象, MessageDigest md=Messa ...

  8. Mac安装Mysql过程

    1.Mysql官网下载安装包 http://dev.mysql.com/downloads/mysql/ 选择Mac OS X 10.10 (x86, 64-bit), DMG Archive版本下载 ...

  9. poj 1007 DNA Sorting

    DNA Sorting Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 95437   Accepted: 38399 Des ...

  10. AndroidListview 滑动过程中图片显示重复错乱解决方案

    主要分析Android中Listview滚动过程造成的图片显示重复.错乱.闪烁的原因及解决方法,顺便跟进Listview的缓存机制. 1.原因分析 Listview item 缓存机制:为了使得性能更 ...