Реализация дерева PHP: определение родительской ссылки в цикле рекурсии - PullRequest
0 голосов
/ 01 марта 2010

Вернуться к моему объекту JaxpTree. Предполагается, что дерево преобразует пару связанных таблиц MySQL во вложенное дерево, которое следует следующим отношениям:


    /**
     * 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 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
                        <b><i>? $this->CreateTree($parent_id, "_NodeTable", false)</i></b>
                        : null)
                  )
                : false);
    } // CreateTree()

Когда я пытаюсь вернуть объект с дополнительной родительской ссылкой (см. Курсив), я попадаю в бесконечный цикл рекурсии, и PHP вылетает.

Где я здесь не так?

1 Ответ

0 голосов
/ 01 марта 2010

$ parent_id, который вы указываете в рекурсивном вызове, всегда будет таким же, как тот, который использовался при первом вызове, поскольку, насколько я вижу, он нигде не изменен в вашем коде. Так что это ваша проблема, вы создаете бесконечный цикл, снова и снова вызывая одну и ту же функцию с одинаковыми параметрами.

...