Справочник функций

Ваш аккаунт

Логин:
Пароль:
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:
Убрать блок ВКонтакте навсегда

Последние темы форума

Показать новые сообщения »

Почтовая рассылка



Подписчиков: 19017
Последний выпуск: 23.04.2012

Построение дерева иерархии с помощью PHP / MySQL

http://www.activex.net.ru/

Рассмотрим пример построения дерева иерархии (в развернутом виде) на основе информации из базы данных с помощью PHP и MySQL. Ключ к решению данной задачи - использование рекурсивной функции. Иерархия разделов будет храниться в таблице базы данных MySQL.

Ниже на скриншоте показана данная таблица (catalogue):

  • id - первичный ключ таблицы
  • pid - id родительского раздела

Далее напишем следующий PHP-скрипт:

1. Файл dbopen.php (открывает соединение с MySQL)


 <?php
  $hostName = "";
  $userName = "yura";
  $password = "yura";
  $databaseName = "tree";
  if (!($link=mysql_connect($hostName,$userName,$password))) {
 printf("Ошибка при соединении с MySQL !\n");
 exit();
 }
  if (!mysql_select_db($databaseName, $link)) {
 printf("Ошибка базы данных !");
 exit();
 } 
?> 

2. Файл index.php (основной скрипт)

<?php 
include( "dbopen.php" ); 

function ShowTree($ParentID, $lvl) { 

global $link; 
global $lvl; 
$lvl++; 

$sSQL="SELECT id,title,pid FROM catalogue WHERE pid=".$ParentID." ORDER BY title";
$result=mysql_query($sSQL, $link);

if (mysql_num_rows($result) > 0) {
echo("<UL>\n");
while ( $row = mysql_fetch_array($result) ) {
$ID1 = $row["id"];
echo("<LI>\n");
echo("<A HREF=\""."?ID=".$ID1."\">".$row["title"]."</A>"."  \n");
ShowTree($ID1, $lvl); 
$lvl--;
}
echo("</UL>\n");
}

}

ShowTree(0, 0); 

mysql_close($link); 

?> 

Всю работу выполняет рекурсивная функция ShowTree(). Ниже на скриншоте показан пример работы index.php:

Оставить комментарий

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.

Комментарии

1. kyle / 28 декабря 2009, 16:48:14
Мне нравитсяМне не нравится

так как у меня структура предполагается быть очень большой порядка 300 элементов, процесс запроса к базе данных только при авторизации, дальше все из сессии =)
а запросы будут очень частыми именно старницы с деревом =( поэтому исключаем все запросы к мускулю и делаем все граматна =)

о структуре и операциях до выведения:
изначально структура была представлена матрицей смежности для ориентированного графа, если граф двудольный будет бесконечный цикл, поэтому не стоит применять, потому как необходимо еще одно условия прерывания цикла, но это мне не нада поэтому, я не делал

потом поиском в ширину от необходимого элемента до всех остальных веток получили список смежности в структуре которого массив из 3х элементов: i - текущая вершина,j - родительская вершина,mark - уровень с 0
Код:
function show_tree($ParentID, $lvl = -1)

{    //// мои глобалки функций

   global $info, $DB;

   $lvl++;

   // text глабальная переменная содержимого на вывод

   $info->text .= '<UL>';

   //главный цикл                        \/количество элементов в стеке (можно воскользоваться стандартной функцией count(array) )

   for( $i = 1; $i < $info->hierar_queue[count]; $i++ )

   {

          // если уровень в списке совпадает с анализируемым в функции и родительский элемент соотвествует текущему

       if($info->hierar_queue[$i][mark] == $lvl and $ParentID == $info->hierar_queue[$i][j])

       {  

          //это понятно

       $ID1 = $info->hierar_queue[$i];

             // тоже

       $info->text .= '<LI>';

             // тоже

       $info->text .= '<A HREF="index.php?act=main&dep='.$ID1.'">'.$DB->query_dep($ID1).'</A><br>';

              // рукурсируем функцию с родительским - текущий и тот же уровень

             // в начале функции он поднимется =)

       $this->show_tree($info->hierar_queue[$i],$lvl);

            // долго я ее дебагил чтобы эту строку чтобы написать

             // возвращаем предыдущий элемент по выходу из функции

       $ParentID = $info->hierar_queue[$i][j];

       }

   }

   //уменьшаем уровень на выходе из функции

   $lvl--;

   $info->text .= '</UL>';

}

2. BugiVugi / 02 августа 2009, 22:22:25
+1 / -0
Мне нравитсяМне не нравится

Думаю не изобрету велосипед если скажу следующее:

Пример наглядный, но явно недоработанный, зато годится для начала объяснения работы с деревьями. Работать с таким деревом не удобно. Очень поможет знать есть ли у узла дети, а также текущий уровень.

| id | pid | child | level | title |
-----------------------------------
| 1 | 0 | 1 | 0 | 1. |
| 2 | 0 | 0 | 0 | 2. |
| 3 | 1 | 0 | 1 | 1.1 |

Проще сразу знать есть ли у узла дети, чем долбить рекурсиями базу.
Уровни тоже вещь очень полезная, позволяют без труда выбирать узлы одного уровня.

3. 747Nook / 23 января 2009, 00:05:32
+0 / -1
Мне нравитсяМне не нравится

Хы когда публиковал скрипт даже не смарел на коментарии ... скрипт сам придумал когда курил в очередной раз а потом сморю у y7u8 точ такойже практически только стиль чуть другой =)

4. 747Nook / 17 января 2009, 03:31:22
+2 / -0
Мне нравитсяМне не нравится

Кодеру руки оторвать ...
connect.php
<?
$db_host = 'localhost';
$db_user = 'root';
$db_pasw = '';
$db_name = 'zendown';
$db_info = mysql_connect($db_host, $db_user, $db_pasw);
mysql_query("SET NAMES `utf8`");
if(!mysql_select_db($db_name, $db_info))
{
print 'Системная ошибка. Повторите попытку через несколько минут!<br>';
echo mysql_error();
echo '<a href="java script:history.back()">Назад</a>';
die();
}
?>



index.php
<?
include "config.php";
function drevoupp($parentId){
$query = mysql_query("SELECT * from drevo");
while($row=mysql_fetch_array($query)){
$title = $row['title'];
$pid = $row['pid'];
$id = $row['id'];
$op = $row['op'];
$idd = $parentId;
if($idd == $pid){
echo "<li><a href=\"#\">$title</a>";
echo "<ul>";
drevoupp($id);
echo "</ul>";
echo "</li>";
}
}
}
drevoupp(0);
?>

5. dodther / 22 декабря 2008, 02:44:06
+7 / -0
Мне нравитсяМне не нравится

афтар. убейся об стену. это самый ужасный код для построения дерева. который тока можно придумать.
тока в твоем примере 16!!! запросов в базу
а если категорий будет больше раза в в 3-4???

6. y7u8 / 29 июня 2007, 11:34:33
+1 / -1
Мне нравитсяМне не нравится

Так и не понял зачем там уровень? Куда проще так
Код:
function ShowTree ($parent_id) {   

    $sql = "SELECT `tree_id`, `parent_id`, `title` FROM `tree` WHERE `parent_id` = $parent_id ORDER BY `title`";

    $result = mysql_query($sql);   

    if (mysql_num_rows($result) > 0) {

        echo '<ul>';       

        while ($row = mysql_fetch_array($result)) {

            echo '<li><a href="/?tree_id='.$row['tree_id'].'">'.$row['title'].'</a></li>';

            ShowTree ($row['tree_id']);            

        }      

        echo '</ul>';

    }  

}



ShowTree (0);

7. y7u8 / 29 июня 2007, 11:33:28
+1 / -0
Мне нравитсяМне не нравится

8. Rusty Cat / 10 декабря 2005, 15:57:40
+0 / -1
Мне нравитсяМне не нравится

А смысл в том, что без global $lvl можно было б не выполнять оператор $lvl--; а куда ж без него:)
а оптимизировать число запросов имхо не возможно, здесь же нет какой либо зависимости - дерево, оно и есть дерево

9. pribor / 11 ноября 2005, 15:24:55
Мне нравитсяМне не нравится

<blockquote><small>Цитата:<hr size=1>
function ShowTree($ParentID, $lvl) {
...
global $lvl;
[/quote]

если global - какой смысл в параметре $lvl ?

Да и в принципе - сколько будет запросов к таблице с приличным числом записей
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог