Дерево категорий бесконечная вложенность

antras2007

Новичок
Доброго всем времени суток. Подскажет пожалуйстя, нужно вернуть дерево в виде массива. В базе три столбца: id, category, parent_category.

нужно сделать это с помощью рекурсии
что то вроде этого но что бы работало
PHP:
  static function tree($parent_category = 0, $lvl = 0)
  {
  $categories = Category::where('parent_category', '=', $parent_category)->get();
  $i = 0;
  $childs = array();
  if(count($categories) > $i){
  foreach($categories as $category){
  $childs[] = $category;
  if($category->parent_category > 0){
  $childs[]['child'] = $category;
  }
  self::tree($category->id);
  $i++;
  $lvl--;
  }
  }

  return $childs;
  }
ни как не получается соорудить массив в виде дерева. Если кто знает как это сделать, то если можно напишите пожалуйста на моем примере.
 

antras2007

Новичок
Такое я уже писал

PHP:
  function left_menu($parent_category, $lvl)
  {


  $this->mysqli = connectdb::getInstance();
  $this->mysqli->query("set names 'utf8'") or die(mysqli_error($this->mysqli));
  $query = "select * from categories where parent_category = " . $parent_category . " order by category";
  $result = $this->mysqli->query($query) or die(mysqli_error($this->mysqli));
  if (mysqli_num_rows($result) > 0) {
  echo "<ul style='list-style-type: none;' \n>";
  while ($row = mysqli_fetch_array($result)) {
  $id = $row["id"];
  echo "<li\n>";
  echo("<a href='" . "?id=" . $id . "'>" . $row["category"] . "</a>" . "  \n");
  echo "</li\n>";
  $this->left_menu($id, $lvl);
  $lvl--;
  }

  echo "</ul\n>";
  }
  }
мне нужно именно вернуть массив в виде дерева

PHP:
[
       'id' = 1'
       'category' = 'computers'
       'parent_category' = 0
       'childs' = [
                 'id' = 2,
                 'category' = 'lenovo'
                 'parent_category' = 1
                      ]
     
       'id' = 3'
       'category' = 'phone'
       'parent_category' = 0
       'childs' = [
                
                 'id' = 4,
                 'category' = 'iphone'
                 'parent_category' = 3
                      ]
]
вот что то типо этого. У меня не получается соорудить сам массив древовидный.
 
Последнее редактирование:

Страшный Злодей

Бывший член клуба (достало хамство).
antras2007, уточните пожалуйста, как в результате запроса:
Код:
select * from categories where parent_category = " . $parent_category . " order by category";
могут появится элементы массива с разными значениями parent_category:
Код:
[
      'id' = 1'
      'category' = 'computers'
      'parent_category' = 0
      'childs' = [
                'id' = 2,
                'category' = 'lenovo'
                'parent_category' = 1
                      ]

      'id' = 3'
      'category' = 'phone'
      'parent_category' = 0
      'childs' = [
           
                'id' = 4,
                'category' = 'iphone'
                'parent_category' = 3
                      ]
]
?

Попробуйте так:
Код:
"select * from categories order by parent_category, category";
Если для parent_category нужен определенный диапазон, то используйте BETWEEN

А дальше все станет понятнее ;)
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
Страшный Злодей, ты сам его запутка, лезешь без понятия. По ссылке всё что ему нужно. Если бы ты понимал в ООП, то увидел бы, что дерево он уже выводил.
 

Страшный Злодей

Бывший член клуба (достало хамство).
AmdY, думаю Вам следует хоть иногда вникать в посты тех веток, где участвуете в обсуждении.
Вот это читали? Мой пост по этому поводу хоть глянули? Что ни так?

Нет, ну может я вообще не понял, что хочет ТС... Тогда, если он тут ещё появится, то пусть отпишет, что ему в результате помогло..
 

antras2007

Новичок
Вы наверное не так меня поняли мну нужно из вот этого
PHP:
public function menu(){
    $categories = DB::table('categories')->get();
    $childs = array();
    foreach ($categories as $category) {
         $childs[$category->parent_category][] = $category;
    }
    foreach($categories as $category){
        if(isset($childs[$category->id])){
            $category->childs = $childs[$category->id];
         }
    }
    $tree = $childs[0];
    return $tree;}
оно как раз выводит то что мне нужно, но мне нужно сделать это в рекурсии. Нужно что бы получилось что то вроде этого
PHP:
['id' = 1'
 'category' = 'computers'
 'parent_category' = 0
 'childs' = [
            'id' = 2,
            'category' = 'lenovo'
            'parent_category' = 1
            ]
 
 'id' = 3'
 'category' = 'phone'
 'parent_category' = 0'
  childs' = [
               'id' = 4, 
               'category' = 'iphone'
               'parent_category' = 3]
]
 
Последнее редактирование:

Страшный Злодей

Бывший член клуба (достало хамство).
Значит не так понял. AmdY, был прав.

Только не пойму, к чему тогда это? Если Вы пишите, что так пробовали и не получилась структура описанная ниже...
 

antras2007

Новичок
Мне нужно в фреймворке соорудить массив и отправить его во views вот для чего а тот метод который с выводом на экран так не передается что бы было красиво. Можно осуществить, но это очень не правильно
 

Страшный Злодей

Бывший член клуба (достало хамство).
Оооооо! OOP, MVC... Ну тогда я пасую, это точно не по моей части :)
Хотел тут на днях ознакомится (в соседней ветке), но чего-то желание на ближайшее время отбито :))))
 

antras2007

Новичок
Тут не важно фреймвор это или нет, то что мне нужно, делают и не во фреймворке
 

Страшный Злодей

Бывший член клуба (достало хамство).
Тогда таки гляньте, на то, что я написал выше. И если это поможет разобраться, то обязательно отпишите. А я завтра с утра встану, порадуюсь и буду дразнить AmdY, нельзя позволить злу победить! :)
 

AnrDaemon

Продвинутый новичок
ОП, тебе совершенно точно не нужно вынимать ВСЁ дерево из БД за один вызов.
Ну вот совершенно, абсолютно не нужно.
 

antras2007

Новичок
Как раз таки нужно за один вызов. Вы предлагаете сделать это несколькими запросами? Но это нагружает сервер.
Я так понимаю идей ни у кого нет. Ладно буду ковыряться сам. Спс всем кто откликнулся.
 

Sufir

Я не волшебник, я только учусь
ОП, тебе совершенно точно не нужно вынимать ВСЁ дерево из БД за один вызов.
Ну вот совершенно, абсолютно не нужно.
Ну, если там всего два-три десятка записей и больше не будет, то я бы тоже одним запросом выдернул всё, а потом распихал по веткам...

Как раз таки нужно за один вызов. Вы предлагаете сделать это несколькими запросами? Но это нагружает сервер.
Я так понимаю идей ни у кого нет. Ладно буду ковыряться сам. Спс всем кто откликнулся.
Ты сначала сделай, а потом нагрузку замерять будешь. Если вдруг действительно не приемлемо будет, тогда и "ковыряйся", что б оптимизировать. Например в кеш положишь своё дерево.
 

Активист

Активист
Команда форума
Можно и без рекурсии, быстрее чем с ней.
PHP:
/**
    * Построение дерева объектов
    * @param array $objects
    * @return self
    */
    public function buildTree(array &$objects) {

        $index = array();
        $relations = array();

        foreach($objects as $key => $object) {

            $index[$object->getId()] = $object->setChildren(array());

            if (isset($index[$object->getParentId()]) && $object->getParentId()) {

                $index[$object->getParentId()]->addChildren($object);

            } else {

                $relations[$object->getParentId()][] = $object;
            }
       
            if ($object->getParentId()) {

                unset($objects[$key]);
            }
        }
   
        foreach ($relations as $parent => $children) {

            foreach ($children as $_children) {

                if ($parent && isset($index[$parent])) {

                    $index[$parent]->addChildren($_children->setParent($index[$parent]));
                }
            }
        }
        return $this;
    }
 

Redjik

Джедай-мастер
Почитал тему — одна риторика в голове?
почему люди так боятся nested set?
почему хотят всегда все одним запросом получать? лишний 10ок запросов на вашем "бложике" ну вообще никакой нагрузки не сделает... (сам страдал такой фигней одно время)
 

Активист

Активист
Команда форума
Почитал тему — одна риторика в голове?
почему люди так боятся nested set?
почему хотят всегда все одним запросом получать? лишний 10ок запросов на вашем "бложике" ну вообще никакой нагрузки не сделает... (сам страдал такой фигней одно время)
Щито!? Разработчик 1С Битрикс?)) При дереве в 100 элементов, это 100 запрос. У нас есть магазинчик электрики, там более полутра тысяч категорий :)
 
Сверху