Noget i retning af dette.
<?php
class Node{
private $id;
private $parent_id;
private $subnodes=array();
private $data;
public function __construct($id,$data,$parent_id=null){
$this->id=$id;
$this->data=$data;
$this->parent_id=$parent_id;
}
public function addSubnode($node){
$this->subnodes[]=$node;
}
public function subnodeCount(){
return count($this->subnodes);
}
public function &getSubnode($index){
return $this->subnodes[$index];
}
public function &getSubnodes(){
return $this->subnodes;
}
public function getData(){
return $this->data;
}
public function setData($data){
$this->data=$data;
}
public function getId(){
return $this->id;
}
public function getParentId(){
return $this->parent_id;
}
}
function buildNodeTree($resource,$func){
$nodes=array();
$tree=array();
while($re=$func($resource)){
$nodes[$re['id']]=new Node($re['id'],$re['data'],$re['parentid']);
}
foreach($nodes as $key=>$node){
if($node->getParentId()==null||$node->getParentId()==0){
$tree[]=&$nodes[$key];
}else{
if(array_key_exists($node->getParentId(), $nodes)){
$nodes[$node->getParentId()]->addSubnode($nodes[$key]);
}else{
echo 'missing key '.$node->getParentId();
var_dump($node);
var_dump($nodes);
}
}
}
return $tree;
}
function walkNodeTree($nodes,$arrive,$leave,$follow,$startFollow=null,$endFollow=null){
foreach($nodes as $node){
$arrive($node);
if($follow($node)&&$node->subnodeCount()>0){
if($startFollow!=null){
$startFollow($node);
}
walkNodeTree($node->getSubnodes(),$arrive,$leave,$follow,$startFollow,$endFollow);
if($endFollow!=null){
$endFollow($node);
}
}
$leave($node);
}
}
//TEST and EXAMPLE code below
$menu=array();
for($i=1;$i<49;$i++){
$p=$i-1;
$menu[]=array($i,$p,"Id ".$i." parent ".$p);
}
shuffle($menu);
reset($menu);
function reader(&$list){
if($data=current($list)){
next($list);
return array('id'=>$data[0],'parentid'=>$data[1],'data'=>$data[2]);
}else{
return false;
}
}
function inSubtree(&$node){
foreach($node->getSubnodes() as $snode){
if($snode->getId()==$_GET['id']){
return true;
}
if(inSubtree($snode)){
return true;
}
}
return false;
}
function follow(&$node){
if($node->getId()==$_GET['id']){
return true;
}
return inSubtree(&$node);
}
function startFollow(&$node){
print '<ul>';
}
function arrive(&$node){
if($node->getId()==$_GET['id']){
print '<li><b>'.$node->getData().'</b>';
}else{
print '<li>'.$node->getData();
}
}
function endFollow(&$node){
print '</ul>';
}
function leave(&$node){
print '</li>';
}
$_GET['id']=rand(1,49);
$tree=buildNodeTree($menu,"reader");
walkNodeTree($tree,'arrive','leave','follow','startFollow','endFollow');
?>