数据库设计:
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
"  p;";
}
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
" ";
}
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']);
?>
图片效果如下:
首页初始化时如下:
全部展开时如下
以下是部分展开的两个效果图: