Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: пометить дерево sql - запроса в многомерный массив [2]

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (2): « 1 [2]   

> Без описания
Мелкий Супермодератор
Отправлено: 09 Мая, 2011 - 14:39:27
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




jonston пишет:
Получился двухмерный массив.А нужен многомерный массив с неограниченной вложенностью.

А можете рассказать, зачем вам именно сам массив древовидный? Его же все равно той же самой рекурсией выводить. Так какая разница, рекурсивно уточнять, существует ли $arr[ нужный подраздел ] или опять же уточнять, существует ли $cat_date[\w+]([\w+])*[\w+]


-----
PostgreSQL DBA
 
 Top
Champion Супермодератор
Отправлено: 09 Мая, 2011 - 15:21:22
Post Id



Активный участник


Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008  
Откуда: Москва


Помог: 57 раз(а)




http://forum.php.su/topic.php?fo...1&topic=2497 вот тут долго и подробно разбирался вывод категорий и подкатегорий. Правда, загажено немного, но разобраться можно.
Дело в том, что многомерный массив с беконечным уровнем вложенности не нужен, а более эффективно тут подойдет другая структура:
CODE (text):
скопировать код в буфер обмена
  1. array(
  2.         id => array (
  3.                 name => string,
  4.                 child_ids => array(int)
  5.         )
  6. )

либо структура, предложенная Мелким. Они просты и с точки зрения их выборки из базы и с точки зрения построения по ним меню.
(Добавление)
Неограниченная вложенность на самом деле не нужна, а делать запрос за запросом - это очень не здорово.
 
 Top
komprenda
Отправлено: 09 Мая, 2011 - 15:47:01
Post Id


Гость


Покинул форум
Сообщений всего: 105
Дата рег-ции: Май 2011  


Помог: 3 раз(а)




jonston пишет:
Спасибо!Посмотри (ничего что я на ты?) вверху есть две функции которые реализуют именно вывод дерева.Она построена примерно по твоим рекомендациям.
Потом вместо вывода я сделал функцию которая делала конкотенацию строки для передачи ее в "view".Понял что это не удобно.Решил что нужно сначала сделать выборку и занести данные в многомерный массив с большим количеством вложенности.А потом уже передать этот массив в вид, в качестве данных.Именно массив нужен потому , что он гибок в использовании.Например мне не нужно лезть в контроллер чтобы изменить выводимые теги <li></li> на <options></options>.Понимаешь о чем я?


PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3.  
  4.  
  5. $arr[0] = array("id" => 1, "pid" => 0, "data" => "Автомобили");
  6. $arr[1] = array("id" => 2, "pid" => 1, "data" => "Легковые");
  7. $arr[2] = array("id" => 3, "pid" => 1, "data" => "Грузовые");
  8. $arr[3] = array("id" => 4, "pid" => 2, "data" => "Купе");
  9. $arr[4] = array("id" => 5, "pid" => 2, "data" => "Седан");
  10. $arr[5] = array("id" => 6, "pid" => 0, "data" => "Работа");
  11. $arr[6] = array("id" => 7, "pid" => 6, "data" => "Резюме");
  12. $arr[7] = array("id" => 8, "pid" => 6, "data" => "Вакансии");
  13.  
  14. function print_tree(&$arr, $parent_id = 0, $level = 0) {
  15.         if ($parent_id > 0) ++$level;
  16.         $childs = array();
  17.         for ($i = 0, $k = count($arr); $i < $k; ++$i) {
  18.                 $pid = intval($arr[$i]["pid"]);
  19.                 if ($pid == $parent_id) {
  20.                         $childs[] = $arr[$i];
  21.                         unset($arr[$i]);
  22.                 }
  23.         }
  24.  
  25.         $arr = array_values($arr);
  26.         for ($i = 0, $k = count($childs); $i < $k; ++$i) {
  27.                 echo '<div style="padding-left: ' . ($level * 10) . 'px;">&raquo; ' . $childs[$i]["data"] . '</div>';
  28.                 print_tree($arr, (int) $childs[$i]["id"], $level);
  29.                 if ($level > $parent_id + 1) {
  30.                     --$level;
  31.                 }
  32.         }
  33. }
  34.  
  35. print_tree($arr);
  36.  
  37. ?>
  38.  


CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. » Автомобили
  3.         » Легковые
  4.                 » Купе
  5.                 » Седан
  6.         » Грузовые
  7. » Работа
  8.         » Резюме
  9.         » Вакансии
  10.  


Короче выбираешь всё сортируешь по id родителя выводишь с помощью функции что я написал.

(Отредактировано автором: 09 Мая, 2011 - 15:57:42)

 
 Top
komprenda
Отправлено: 09 Мая, 2011 - 22:46:36
Post Id


Гость


Покинул форум
Сообщений всего: 105
Дата рег-ции: Май 2011  


Помог: 3 раз(а)




EuGen пишет:
jonston пишет:
Как это решить без рекурсии?

Без рекурсии у Вас не получится. Вам же нужна неограниченная вложенность.
Вообще древовидные струкруры в реляционной БД строятся "плохо" - то есть Вам приходится в любом случае делать запрос за запросом.
Иными словами:
0. Делаете запрос на выборку из таблицы, где parent_id=0
1. Пробегаетесь по строкам
2. Делаете запрос на выборку из таблицы, где parent_id=значению в текущей строке.
Для организации рекурсии нужно объединить запрос на выборку и перебор строк в одну функцию, принимающаю параметр id (это parent_id, по которому функция сделает выборку) и возвращающая все строки, у которых parent_id = переданному этой функции id.


этот способ не помню где был описан и почему-то все именно так и делают, хотя это в корне неправильно. зачем делать запрос за запросом, когда можно выбрать всё одним?

(Отредактировано автором: 09 Мая, 2011 - 22:55:46)

 
 Top
EuGen Администратор
Отправлено: 10 Мая, 2011 - 08:55:48
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Потому что это - как правило первое, что приходит в голову. Я упомянул, что древовидные структуры в реляционных БД строить плохо не просто так же.
Выше Champion привел пример для более правильной реализации (двумерный массив). Правда, это только для частного случая - а именно когда подчиненные объекты имеют одну и ту же структуру. В общем же случае (когда потомки могут иметь атрибуты, отсутствующие у предков), такой структурой, увы, не обойтись.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Страниц (2): « 1 [2]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Работа с СУБД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB