<?php
// mock result set
$rows = array(
array(
'id'=>1
,'parent_id'=>null
,'name'=>'Home'
)
,array(
'id'=>2
,'parent_id'=>null
,'name'=>'About'
)
,array(
'id'=>3
,'parent_id'=>2
,'name'=>'Me'
)
,array(
'id'=>4
,'parent_id'=>2
,'name'=>'Company'
)
,array(
'id'=>5
,'parent_id'=>null
,'name'=>'Portfolio'
)
,array(
'id'=>6
,'parent_id'=>5
,'name'=>'Web'
)
,array(
'id'=>7
,'parent_id'=>5
,'name'=>'Writing'
)
,array(
'id'=>8
,'parent_id'=>6
,'name'=>'Design'
)
,array(
'id'=>9
,'parent_id'=>6
,'name'=>'Programming'
)
);
/*
UNTESTED
$rows = array();
$sql = 'SELECT * FROM {table}'; -- replace * with proper columns and {table} w/ table name
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result) ) {
$rows[] = $row;
}
*/
// covert raw result set to tree
$menu = convertAdjacencyListToTree(null,$rows,'id','parent_id','links');
// echo '<pre>',print_r($menu),'</pre>';
// display menu
echo themeMenu($menu,1);
/*
* ------------------------------------------------------------------------------------
* Utility functions
* ------------------------------------------------------------------------------------
*/
/*
* Convert adjacency list to hierarchical tree
*
* @param value of root level parent most likely null or 0
* @param array result
* @param str name of primary key column
* @param str name of parent_id column - most likely parent_id
* @param str name of index that children will reside ie. children, etc
* @return array tree
*/
function convertAdjacencyListToTree($intParentId,&$arrRows,$strIdField,$strParentsIdField,$strNameResolution) {
$arrChildren = array();
for($i=0;$i<count($arrRows);$i++) {
if($intParentId === $arrRows[$i][$strParentsIdField]) {
$arrChildren = array_merge($arrChildren,array_splice($arrRows,$i--,1));
}
}
$intChildren = count($arrChildren);
if($intChildren != 0) {
for($i=0;$i<$intChildren;$i++) {
$arrChildren[$i][$strNameResolution] = convertAdjacencyListToTree($arrChildren[$i][$strIdField],$arrRows,$strIdField,$strParentsIdField,$strNameResolution);
}
}
return $arrChildren;
}
/*
* Theme menu
*
* @param array menu
* @param runner (depth)
* @return str themed menu
*/
function themeMenu($menu,$runner) {
$out = '';
if(empty($menu)) {
return $out;
}
$out.='<ul>';
foreach($menu as $link) {
$out.= sprintf(
'<li class="depth-%u">%s%s</li>'
,$runner
,$link['name']
,themeMenu($link['links'],($runner+1))
);
}
$out.='</ul>';
return $out;
}
?>
Replace mock result set with the real result set and there you go. Also, Im not sure what the root level parent is in your actual case. In the code I provided its assumed to be null, so that may need to be changed if its 0 or some other value.
// covert raw result set to tree
$menu = convertAdjacencyListToTree(null,$rows,'id','parent_id','links');
The first argument is the value for the root level menu items. So if the actual value is 0 rather than null it would need to be changed to the below instead.
// covert raw result set to tree
$menu = convertAdjacencyListToTree(0,$rows,'id','parent_id','links');