2016-09-23 1 views
0

У меня есть таблица базы данных с родительскими строками, одним родительским числом, связанным по полю «parent».Итерировать родительские дети без использования рекурсивного PHP

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

Top 1 >> Level 1 >> Level 2 >> Level 3 
    Top 2 >> Level 1 
    Top 3 >> Level 1 >> Level 2 

    $parent = array(); 
    array_push($parent, 0); 
    while(!empty($parent)){ 
    foreach($parent as $key => $mother){ 
     unset($parent[$key]);  
     $sql = "SELECT * FROM levels WHERE parent = " . $mother; 
     $res = mysql_query($sql); 
     while($row=mysqli_fetch_object($res)){ 
     print $row->name . "<br />"; 
     array_push($parent, $row->id); 
     } // while 
    } // foreach 
    } // while 

Результатом этого кода

Top 1 Top 2 Top 3 Уровень 1 ...

+0

Не было бы проще выбрать все данные, которые вам нужны в одном запросе, а затем что-то сделать с ним? – simon

+0

В случае рекурсивной функции, я думаю, что намного проще использовать несколько SELECT. В любом случае вы можете думать о массиве, заполненном той же структурой, что и в базе данных. Как вы перебираете его, чтобы перечислить данные предпочтительным образом? Рекурсия очень проста, я прошу не рекурсивный способ. – Cesar

ответ

1

Самый большой вопрос здесь почему вы хотите в нерекурсивна образом? Увидев, что у вас несколько, и это кажется неопределенным, уровни дочерних узлов, это именно то, что выделяют рекурсивные функции.

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

Same parent == same leaf 
Different parent && parent == previous id, new leaf 
Different parent { when (parentList[idx--] == parent) == change leaf to idx leaf. 

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

Еще одна вещь, которую я хотел бы прокомментировать, - это использование вами запроса внутри цикла. Выполнение этого, как правило, очень плохо, так как это увеличит время потребления вашего кода по экспоненте. Гораздо лучше получить все узлы в одном запросе, отсортированные по родительским и идентификационным номерам. Таким образом, вам не нужно ждать (n-1) * y ms (или больше) дополнительно, где n - количество записей, а y - время, необходимое для запуска запроса один раз.
Если запрос занимает 20 мс для запуска, и у вас есть 300 записей, вы смотрите на дополнительное время ожидания почти 6 секунд! Просто потому, что вы переместили запрос внутри цикла, а не сортировали его правильно (или используя JOIN).
Как вы можете видеть, есть много результатов, полученных при правильном структурировании кода. Не только это, но и будет намного легче читать и, следовательно, поддерживать ваш код.

Реферат: Используйте рекурсивные функции, так как это то, для чего они созданы, и переместите ваши запросы за пределы циклов.

+0

Это был просто интерес. Что касается SQL-запроса внутри цикла, вы совершенно правы. Я сделал это так, чтобы не использовать память PHP в огромных массивах, но в других сценариях, отличных от тех, в которых я привык, вы правы, что это резко снизит эффективность. – Cesar

+0

Рад, что я мог помочь. Всегда приятно помогать другим учиться, особенно когда они любопытны и готовы это сделать. :) Продолжайте хорошую работу! – ChristianF