PHP tree implementation: Defining parent reference on recursion loop
Back to my JaxpTree object. The tree is supposed to convert a MySQL related-table pair into a nested tree that follows such relationship:
/**
* Generates a JaxpTree structure. Parameters are used by the recursive
* function. Normally, they shouldn't be specified.
*
* @param int $parent_id
* @param string $source_table
* @param bool $include_childs
*
* @access public
* @return JaxpTree
* @since 1.0
*/
function CreateTree(
$parent_id = 0,
$source_table = "_NodeTable",
$include_childs = true
)
{
# Copy field names to local variables for shortness.
$pfId = $this->_ParentIdField;
$fId = $this->_IdField;
$fL = $this->_LabelField;
# Determine source table. The iteration begins using NodeTable,
# then, to fetch the items, uses ItemTable.
$source_table = !$source_table ? "_NodeTable" : $source_table;
# Get all rows from the source table.
$rows = $this->{$source_table}->GetById($pfId, $parent_id, true);
# If no rows, no process will be done.
if ($rows)
{
# Iterate through the row list.
foreach ($rows as $r)
{
# Get label and id values.
$label = $r->Columns[$fL]->Value;
$id = $r->Columns[$fId]->Value;
# If this node has childrens...
if ($this->{$source_table}->GetById($pfId, $id) && $include_childs)
{
# Do recursive call using this node as root.
$array[$label] = $this->CreateTree($id);
# If this node has items...
if ($this->_ItemTable->GetById($pfId, $id))
{
# Do recursive call using this node as root
# scanning the item table.
$array[$label]->ItemList = $this->CreateItemList($id);
}
}
else # This node has no child, so there's no need for
# more nested trees.
{
# Create a new TreeNode.
$new_node = new JaxpTreeNode($id);
# Send a JaxpMySqlRow object to the node.
# This will turn the row into node elements.
$new_node->LoadFromMySqlRow($r);
# Store开发者_如何学JAVA the node.
$array[] = $new_node;
if ($source_table != "_ItemTable")
{
$array[$new_node->Attributes->Get($fL)->Value] = $new_node;
}
# If the node has items...
if ($this->_ItemTable->GetById($pfId, $id))
{
# Do recursive call using this TreeNode as root
# scanning the item table.
$new_node->ItemList = $this->CreateItemList($id);
}
} # End checking for children.
} # End iterating the row list.
} # End checking for rows.
# Return a JaxpTree object, using the array as contents.
return (isset($array)
? new JaxpTree(
$array, null,
($parent_id
? $this->CreateTree($parent_id, "_NodeTable", false)
: null)
)
: false);
} // CreateTree()
When I attempt to return the object with the additional parent reference (see italic line), I get caught in an endless recursion loop and PHP crashes.
Where am I going wrong here?
The $parent_id you provide in the recursive call will always be the same as the one that was used on your first call, since it's not modified anywhere in your code as far as I see. So that's your problem, you create an infinite loop by calling the same function with the same parameters over and over again.
精彩评论