这个是经过本人实践确实可以使用的。
先说下表结构。一共三个字段iClassID,iParentID,cClassName;
一个是分类的id,一个是父id,一个是分类的名字,
下面是代码:
<?php
class Tree
{
/*
*在这里需要注意的是,类需要传入一个数组。即分类的全部数据,是一个二维的数组
*
*/
//分层
private $view;
//private $path;
private $data=array();//id=>信息
private $cateArray=array();//id=>pid
public function __construct($dataArray)
{
foreach ($dataArray as $val)
{
$this->setNode($val['iClassID'], $val['iParentID'], $val['cClassName']);
}
$this->sortASC();
}
//设置树的节点
function setNode($id, $parent, $value)
{
$parent = $parent?$parent:0;
$this->data[$id] = $value;
$this->cateArray[$id] = $parent;
}
/*
* 递归实现
* 得到id下的子树结构数组(用多维数组格式来表示树)
* id Internet 节点id (0表示的是根节点,是虚拟的,即没有与它对应的实际信息)
* return array 子树节点数组
*/
function getChildsTree($id=0)
{
$childs=array();
foreach ($this->cateArray as $child=>$parent)
{
if ($parent==$id)
{
$childs[$child]=$this->getChildsTree($child);
}
}
return $childs;
}
/*
* 递归实现
* 得到id节点的所有后代节点
* $id
* return array 索引=>id,...一维数组(顺序important)
*/
function getChilds($id=0)
{
$childArray = array();
$childs = $this->getChild($id);
foreach ($childs as $child)
{
$childArray[]=$child;
$childArray=array_merge($childArray,$this->getChilds($child));
}
return $childArray;
}
/*
* 得到id节点的孩子节点
* $id
* return array 索引=>id,...一维数组
*/
function getChild($id)
{
$childs=array();
foreach ($this->cateArray as $child=>$parent)
{
if ($parent==$id)
{
$childs[]=$child;
}
}
return $childs;
}
/*
* 递归实现
* 反线获得节点id的父节点
* $id interger 不可以为0
* return array 其父节点数组
*/
function getNodeLever($id)
{
$parents=array();
if (array_key_exists($this->cateArray[$id],$this->cateArray))//它的父节点,在节点树中
{
$parents[]=$this->cateArray[$id];
$parents=array_merge($parents,$this->getNodeLever($this->cateArray[$id]));
}
return $parents;
}
/*
* 根据所在层数得到n-1个前导格式化符号
* $id Internet 不可以取0
* $preStr str 填充的格式化符号
* return str 多个格式化符号
*/
function getLayer($id,$preStr='|-')
{
return str_repeat($preStr,count($this->getNodeLever($id)));
}
//得到id节点的信息
function getValue ($id)
{
return $this->data[$id];
}
/*
* id降序
*/
function sortDES()
{
krsort($this->cateArray);
}
/*
* id升序
*/
function sortASC()
{
ksort($this->cateArray);
}
//下拉列表框样式,
function select($cid = 0){
$category = $this->getChilds(0);
//file_put_contents('log.txt',var_export($category,true));
foreach ($category as $key=>$id)
{
if($cid == $id){
$this->view .= "<option value='$id' selected='selected'>".$this->getLayer($id, '|-').$this->getValue($id)."</option>";
}
else{
$this->view .= "<option value='$id'>".$this->getLayer($id, '|-').$this->getValue($id)."</option>";
}
}
return $this->view;
}
//表格样式
function view()
{
$category = $this->getChilds(0);
foreach ($category as $key=>$id)
{
$this->view .= "<tr><td>".$this->getLayer($id, '|-').$this->getValue($id)."</td><td><a href='edit/id/$id'>编辑</a>|<a href='del/id/$id' onclick='if(confirm('是否确定删除')==false)return false;' >删除</a></td></tr>";
}
return $this->view;
}
//endallfunc所有函数结束
}
?>
require("Tree.php");
mysql_connect('localhost','root','');
mysql_select_db('test');
mysql_query('set names utf8');
$result = mysql_query("select * from t_class");
$data = array();
while ($row = mysql_fetch_array($result)){
$data[] = array('iClassID'=>$row['iClassID'],'iParentID'=>$row['iParentID'],'cClassName'=>$row['cClassName']);
}
$t = new Tree($data);
this->assign('class',$t->view());//表格样式,主要是用来编辑和删除分类
$this->assign('sclass',$t->select($id));//这里需要传一个父id,当编辑的时候,以便标识此分类所在的父分类为选中状态,如果为0 则显示的是分部分类
$this->display();
<table>
{$class}//表格样式
</table>
<select name='iParent'>
<option value='0'>---根分类---</option>
{$sclass}//下拉列表样式
</select>
最终效果如图: