I have written a solution based on my earlier outline. As Scott pointed out, there are other ways of doing this. This is a single parent model. It can be extended to include multiple parents with some (what I believe to be) minor modifications.
I learned a few things about references (not quite pointers) in PHP along the way. I may write this up as a NUM.
If anyone has any questions in the meantime, let me know.
Code:
**** sample main loop for building and printing a tree structure
**** include file to follow for Hierarchy class
<?
include "hierarchy.inc";
$username = "user";
$password = "pass";
$databasename = "test";
$link = mysql_connect($hostname, $username, $password);
mysql_select_db($databasename, $link);
$stmt = "select id, parent_id, description from hierarchy";
$result = mysql_db_query($databasename, $stmt);
$object = array(); /* lookup table of references to objects */
//$object["0"] = new Hierarchy(0); -- will be added automatically
//$object["0"]->setDesc("root");
while ($row = mysql_fetch_object($result)) {
if (is_null($object["$row->id"])) { /* if object doesn't already exist */
$tmp_obj = &new Hierarchy($row->id);
} else {
$tmp_obj = &$object["$row->id"]; /* lookup existing object */
}
$tmp_obj->setParent_id($row->parent_id);
$tmp_obj->setDesc($row->description);
$object["$row->id"] = &$tmp_obj; /* add object reference to lookup
table */
if (is_null($object["$row->parent_id"])) { /* if parent doesn't already exist,
create it */
$tmp_obj2 = &new Hierarchy($row->parent_id);
$object["$row->parent_id"] = &$tmp_obj2;
} else {
$tmp_obj2 = &$object["$row->parent_id"];
}
$tmp_obj2->addChild($row->id);
} /* end of while loop to load data */
mysql_free_result($result); /* free resultset */
/* print entire tree starting at root node - 0 */
$object[0]->printChildren(0, $object);
?>
*** include file "hierarchy.inc" ***
The Hierarchy Class (each node with a list of it's children)
Code:
<?
class Hierarchy {
var $id;
var $parent_id;
var $description;
var $children;
var $level;
function Hierarchy($new_id) {
$this->setId($new_id);
$this->children = array();
}
function setId($new_id) {
$this->id = $new_id;
}
function setParent_id($newParent_id) {
$this->parent_id = $newParent_id;
}
function setDesc($desc) {
$this->description = $desc;
}
function addChild($child_id) {
$this->children[] = $child_id;
}
function printDesc($num_tabs) {
$tab = "&nbsp; &nbsp; &nbsp;";
for ($i=1; $i<=$num_tabs; $i++ ) {
$tabs = $tabs.$tab;
}
print $tabs.$this->description;
print "<BR>";
}
function printChildren($tree_lvl, &$hashtab) {
/* loop through array of $children, print $description, */
/* call printChildren(); stop when all children are processed */
$this->level = $tree_lvl;
foreach ($this->children as $child) {
$hashtab["$child"]->printDesc($this->level + 1);
$hashtab["$child"]->printChildren($this->level + 1,$hashtab);
}
}
}
?>