Welcome to php club

Деревья в базах данных => Пропущенные фразы => K

Пропущенные фразы

Как прорисовать дерево в php из MSSQL


Reader
Прорисовывается дерево со вложенными обьектами. Используется рекурсия.
Таблица на сервере mssql sp_struct
id integer Идентификатор
parent_id integer родитель
name char(40) наименование


<?php
if (empty($filial)) $filial=0;

function
top($db,$filial,$parent)         {
$result = odbc_exec ($db, "SELECT     * FROM         sp_struct sp WHERE     (id = $parent)");
while(
odbc_fetch_into($result,$row))     {
$str=top($db,$parent,$row[1])."<a target=big href = tree.php?filial=$row[0]>$row[2]</a>>>>";
return
$str;
}
}


function
sub_tree($i,$db)         {
$result = odbc_exec ($db, "SELECT id, parent_id, name FROM sp_struct WHERE ID='$i' OR  parent_id='$i' ORDER BY id ASC");

odbc_fetch_into($result,$row);
print
"<li id='foldheader'>".trim($row[2])." &nbsp<a target=big href=tree.php?filial=$row[0]> перейти</a>";

print
"<ul id='foldinglist' style='display:yes' style='&{head};'>";
    while(
odbc_fetch_into($result,$row))
{
sub_tree($row[0],$db);}
print
"</ul>";    }



$db= odbc_connect ($dbhost, $dbuser, $dbpasswd);
$RS = odbc_exec ($db, "SELECT * FROM  sp_struct where id=$filial ORDER BY 1");
if (
$filial!=1)     {print "<font size=1>".top($db,$filial,odbc_result ($RS,2))."</font>";    }
print
"<ul>";
sub_tree($filial,$db);
print
"</ul>";

?>


Добавив вот этот скрипт в конце, получим открывающееся/закрывающееся дерево:


(можно после </body></html>)


<script language="JavaScript1.2">
<!--

function change()
{
  if(!document.all)
    return
  if (event.srcElement.id=="foldheader") {
    var srcIndex = event.srcElement.sourceIndex
    var nested = document.all[srcIndex+2]
    if (nested.style.display=="none") {
       nested.style.display=\'\'
       event.srcElement.style.listStyleImage="url(../images/ope.gif)"
    }
    else {
       nested.style.display="none"
       event.srcElement.style.listStyleImage="url(../images/fol.gif)"
    }
  }
}

document.onclick=change

//-->
</script>


popoff
Хороший пример. Только его нужно в немножко переделать:

  • отформатировать – проставить отступы и интервалы
  • генерировать только валидный html (значения свойств без кавычек, недопустимые символы (>), “ ” без “;", незакрытые теги и т.п.).
  • отделить весь html от данных. Отдельно – загружаем дерево в массив и подготавливаем его к выводу. Отдельно – формирование html. Никакого комбинирования. Когда новички задают вопрос «Как вывести дерево?», возникает естественный вопрос, что именно у них не получается: загрузка данных или фомрирование html? При комбинировании этот вопрос не естественен: у них не получается все, потому что операция «вывода дерева» в таком случае почти как атомарная операция; она либо вся получается, либо вся не получается.
  • указать на то, что формирование html НИКАК не зависит ни от способа хранения дерева, ни от способа подготовки данных. Привести процедуру подготовки данных для случая, если дерево хранится в My SQL?.
  • кто такой "$filial"? Он, видимо, должен возникать при включенном Register Globals. Не выполняется даже элементарной проверки на корректность: можно передать одинарную кавычку – для новичков «самое оно». Для чего он передается внутрь функции top?
  • запросы c OR:
    WHERE ID='".$i."' OR parent_id='".$i."' ORDER BY 
    никогда не используют индексы (по крайней мере в My SQL?, в остальных – не разбирался). Внутри рекурсии дадут жуткие тормоза. Вероятно, два запроса будет быстрее.
  • приведенный Java Script? работает только в IE. Включить хотя бы минимальную кроссбраузерность. Возможно, использовать klayers.
  • не использовать расширение строк ($переменные внутри "") – по вкусу?
  • что означает это:
    print "<ul id='foldinglist' style='display:yes;' style='&{head};'>";
    я так до конца и не понял. зачем два раза style? Если я не ошибаюсь, значение “yes” не является допустимым значением для свойства “display”.
  • странный какой-то пример. Выбирает строки, в которых id или parent_id равен некоторому значению, сортирует их по id и считает, что элемент, у которого id самый маленький, является родителем всех остальных, у которых id больше. Это верно только если в дереве никогда не перемещались узлы.
  • выбирается уровень. вместе с «наименованиями». Из этих всех наименований используется только первое – которое считается родительским для всего уровня. Остальные игнорируются в этом месте и загружаются из базы данных еще раз, когда дело доходит до рекурсивного вызова и текущий ребенок становится родителем.
  • кто такой target="big" в ссылках?
  • если для некоторой вершины нет ни одного дочернего элемента, то будет вставлено "<ul></ul>"
  • сортирует дерево по возрастанию id. Заменить на сортировку по наименованию.
  • вынести «наименование» в отдельную таблицу. Отдельно храним дерево, отдельно – данные.
  • вероятно, можно оставить два примера: этот и тот, который получится после изменения. Потом их сравнить и сказать, какой вариант чем лучше.


 
Комментариев нет. [Показать комментарии/форму]