В общем есть такой вариант решения:
Допустим у нас есть БД 'test' в ней таблица 'tree' с полями: ID, parentID и title (ID узла, ID родительского узла и название соответственно)
функуии вывода структуры дерева и удаления узла вместе со всем поддеревом:
И в зависимости от принятого запроса выполняем те или иные действия
Осталось организовать вывод в браузер и все
З.Ы. Единственное, что тут в рекурсии отправляется SQL запрос. При большом дереве это не очень хорошо, т.к. будет много SQL запросов. Лучше считать дерево в переменную одним запросом и обрабатывать получившийся массив. 8)
Допустим у нас есть БД 'test' в ней таблица 'tree' с полями: ID, parentID и title (ID узла, ID родительского узла и название соответственно)
функуии вывода структуры дерева и удаления узла вместе со всем поддеревом:
//выводим дерево function showTree ($parentID = 0) { $result = ($parentID == 0)? "ROOT <a href=\"/?do=child&ID=0\" ><img src=\"/pic/child.gif\" width=\"16\" height=\"16\" border=\"0\" align=\"absmiddle\" alt=\"Добавить дочернее значение\" /></a>" : ''; $sql = "SELECT * FROM tree WHERE parentID='$parentID' ORDER BY title"; $res = mysql_query($sql); if (mysql_num_rows($res) > 0) { $result .= "<ul>"; while ($row = mysql_fetch_array($res)) { $result .= "<li>".$row['title']." <a href=\"/?do=edit&ID=".$row['ID']."\"><img src=\"pic/edit.gif\" width=\"16\" height=\"16\" border=\"0\" align=\"absmiddle\" alt=\"Редактировать название\"/></a> <a href=\"/?do=child&ID=".$row['ID']."\"><img src=\"/pic/child.gif\" width=\"16\" height=\"16\" border=\"0\" align=\"absmiddle\" alt=\"Добавить дочернее значение\" /></a> <a href=\"/?do=del&ID=".$row['ID']."&sessID=".session_id()." \"><img src=\"/pic/del.gif\" width=\"16\" height=\"16\" border=\"0\" align=\"absmiddle\" alt=\"Удалить узел (удалит и все вложенные поддеревья)\" onClick=\"return Delete_confirm()\" /></a> </li>"; $result .= showTree ($row['ID']); } $result .= '</ul>'; //$result = trim($result," "); } return $result; } //удаляем ветку(вместе с поддеревьями) function deleteSubTree($ID){ $sql = "SELECT ID FROM tree WHERE parentID='$ID'"; $res = mysql_query($sql); if (mysql_num_rows($res) > 0) { while ($row = mysql_fetch_array($res)) { if (!deleteSubTree($row["ID"])) return false; } } $sql = "DELETE FROM tree WHERE ID='$ID' LIMIT 1"; mysql_query($sql); if (mysql_affected_rows() < 1) return false; else return true; return false; } $do = (!empty($_POST['do'])) ? $_POST['do'] : ""; if (empty($_POST['do']) && (!empty($_GET['do']))) $do = $_GET['do']; $error = ""; $out1 = "";
И в зависимости от принятого запроса выполняем те или иные действия
switch ($do) { // редактирование узла case "edit": $sql = "SELECT * FROM tree WHERE ID='".$_GET["ID"]."' LIMIT 1"; $res = mysql_query($sql); if (mysql_num_rows($res) > 0) { $row = mysql_fetch_assoc($res); $out1 .= "<form method=\"post\" action=\"\"> Введите новое название для «".$row["title"]."»: <input type=\"text\" name=\"title\" /> <input type=\"hidden\" name=\"do\" value=\"save\" /> <input type=\"hidden\" name=\"ID\" value=".$_GET["ID"]." /> <input type=\"hidden\" name=\"sessId\" value=\"".session_id()."\" /> <input type=\"submit\" value=\"Сохранить\" /> </form>"; } break; // сохранение отредактированного case "save": if ($_POST["sessId"] != session_id()) exit("Ошибка: попытка передачи данных с другого хоста"); $_POST["title"] = sql_prep(trim (htmlspecialchars($_POST["title"], ENT_QUOTES))); $sql = "UPDATE tree SET title='".$_POST["title"]."' WHERE ID='".$_POST["ID"]."' LIMIT 1"; mysql_query($sql); if (mysql_affected_rows() < 1) $error .= "<strong>Ошибка сохранения названия узла</strong>"; break; // Удаление узла с поддеревом case "del": if ($_GET["sessID"] != session_id()) exit("Ошибка: попытка передачи данных с другого хоста"); if (!deleteSubTree($_GET["ID"])) $error .= "<strong>Ошибка удаления узла</strong>"; break; // Форма ввода нового узла case "child": $out1 .= "<form method=\"post\" action=\"\"> Введите название нового узла: <input type=\"text\" name=\"title\" /> <input type=\"hidden\" name=\"do\" value=\"saveChild\" /> <input type=\"hidden\" name=\"ID\" value=".$_GET["ID"]." /> <input type=\"hidden\" name=\"sessId\" value=\"".session_id()."\" /> <input type=\"submit\" value=\"Сохранить\" /> </form>"; break; // удаление дерева case "saveChild": if ($_POST["sessId"] != session_id()) exit("Ошибка: попытка передачи данных с другого хоста"); $_POST["title"] = sql_prep(trim (htmlspecialchars($_POST["title"], ENT_QUOTES))); $_POST["ID"] = sql_prep(trim (htmlspecialchars($_POST["ID"], ENT_QUOTES))); $_POST["title"] = sql_prep(trim (htmlspecialchars($_POST["title"], ENT_QUOTES))); $sql = "INSERT INTO tree (parentID, title) VALUES ('".$_POST['ID']."', '".$_POST['title']."')"; mysql_query($sql); if (mysql_affected_rows() < 1) $error .= "<strong>Ошибка сохранения узла</strong>"; break; // }
Осталось организовать вывод в браузер и все

З.Ы. Единственное, что тут в рекурсии отправляется SQL запрос. При большом дереве это не очень хорошо, т.к. будет много SQL запросов. Лучше считать дерево в переменную одним запросом и обрабатывать получившийся массив. 8)