多级树的遍历
class MultilevelTree{ private $depth;//深度 private $i; //深度计数器 private static $db ; //数据库对象 public $arr; //节点数据数组 public $deep; //最大深度 function __construct($depth=0) { $this->depth = $depth; $this->i = 0; $this->arr = array(); $this->deep = 0; } static function instanceDb(){ if(!MultilevelTree::instanceDb()){ return new DB(); }else{ return MultilevelTree::instanceDb(); } } /** * 左序遍历 * @param $uid 当前节点的id */ function traversal_left($uid){ $data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid); foreach ($data as $v){ if($v['uid']){ $this->arr[] = $v; $this->traversal_left($v['uid']); } } } /** * 根据层数遍历,并返回不包括本身的所有下层的数组 * @param $uid 当前节点的id */ function getChildren($uid){ $this->i++; $data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid); $this->arr = array_merge($this->arr,$data); if($this->depth > 0){ if($this->i == $this->depth){ $this->i=1; //每当纵向一条树线等于深度时,将深度计数器重置为1 return; } } foreach ($data as $v){ if($v['uid']){ $this->getChildren($v['uid']); } } } /** * 获取整棵树最大深度 * @param $uid 当前节点的id */ function getChildrenDepth($uid){ $this->i++; $data = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$uid); foreach ($data as $v){ if($v['uid']){ $data2 = MultilevelTree::instanceDb()->query('select * from by_distribution where pid = '.$v['uid']); if(!$data2){ if($this->deep < $this->i) $this->deep = $this->i; $this->i=1; //每当没有子节点时,将计数器重置为初始值+1 return; } $this->getChildrenDepth($v['uid']); } } } /** * 获取父级数据 * @param $pid 当前节点的父级id */ function getParent($pid){ $parent = MultilevelTree::instanceDb()->row('select * from by_distribution where uid = '.$pid); if($this->i == $this->depth){ return; } if($parent['pid'] == 0) array_push($this->arr,$parent);//根节点 if($parent['pid']){ array_push($this->arr,$parent); $this->i++; $this->getParent($parent['pid']); } }}
单元测试
class TestMultilevelTree extends PHPUnit_Framework_TestCase{ /** * 获取子节点数量 */ function testGetChildren(){ $mlt = new MultilevelTree(); $mlt->getChildren(1); $this->assertEquals(11,count($mlt->arr)); } /** * 获取子节点最大深度 */ function testGetChildrenDepth(){ $mlt = new MultilevelTree(); $mlt->getChildrenDepth(1); $this->assertEquals(4,$mlt->deep); } /** * 获取获取父节点 */ function testGetParent(){ $mlt = new MultilevelTree(10); $mlt->getParent(2); $this->assertEquals(2,count($mlt->arr)); }}