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

Ваш аккаунт

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

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

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

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

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

Построение дерева иерархии с помощью 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:

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

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
96K
16 сентября 2015 года
Валерчик Куликов
0 / / 16.09.2015
+5 / -1
Мне нравитсяМне не нравится
16 сентября 2015, 17:30:35
да уж писаки.. а никто не догадался одним запросом получить данные в массив, а за тем с этим массивом и работать?
2.
56K
28 декабря 2009 года
kyle
0 / / 28.12.2009
+1 / -2
Мне нравитсяМне не нравится
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>';

}
3.
52K
02 августа 2009 года
BugiVugi
0 / / 02.08.2009
+5 / -0
Мне нравитсяМне не нравится
2 августа 2009, 22:22:25
Думаю не изобрету велосипед если скажу следующее:

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

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

Проще сразу знать есть ли у узла дети, чем долбить рекурсиями базу.
Уровни тоже вещь очень полезная, позволяют без труда выбирать узлы одного уровня.
4.
47K
17 января 2009 года
747Nook
0 / / 17.01.2009
+1 / -2
Мне нравитсяМне не нравится
23 января 2009, 00:05:32
Хы когда публиковал скрипт даже не смарел на коментарии ... скрипт сам придумал когда курил в очередной раз а потом сморю у y7u8 точ такойже практически только стиль чуть другой =)
5.
47K
17 января 2009 года
747Nook
0 / / 17.01.2009
+7 / -1
Мне нравитсяМне не нравится
17 января 2009, 03:31:22
Кодеру руки оторвать ...
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);
?>
6.
46K
22 декабря 2008 года
dodther
0 / / 22.12.2008
+14 / -1
Мне нравитсяМне не нравится
22 декабря 2008, 02:44:06
афтар. убейся об стену. это самый ужасный код для построения дерева. который тока можно придумать.
тока в твоем примере 16!!! запросов в базу
а если категорий будет больше раза в в 3-4???
7.
31K
29 июня 2007 года
y7u8
0 / / 29.06.2007
+8 / -3
Мне нравитсяМне не нравится
29 июня 2007, 11:34:33
Так и не понял зачем там уровень? Куда проще так
Код:
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);
8.
31K
29 июня 2007 года
y7u8
0 / / 29.06.2007
+4 / -2
Мне нравитсяМне не нравится
29 июня 2007, 11:33:28
9.
Аноним
+2 / -3
Мне нравитсяМне не нравится
10 декабря 2005, 15:57:40
А смысл в том, что без global $lvl можно было б не выполнять оператор $lvl--; а куда ж без него:)
а оптимизировать число запросов имхо не возможно, здесь же нет какой либо зависимости - дерево, оно и есть дерево
10.
Аноним
+0 / -3
Мне нравитсяМне не нравится
11 ноября 2005, 15:24:55
<blockquote><small>Цитата:<hr size=1>
function ShowTree($ParentID, $lvl) {
...
global $lvl;
[/quote]

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

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