5
votes

I am creating a questionnaire for a client that requires the questions to be organized by 3 layers of levels. I've successfully created the U.I. however I've been trying for the last 3 hours to pull data from a database in such a way that everything loads in the right place. The database is organized like so by the client so I have no control over it:

id    description    parentId    
1      Level 1        0           
2      Level 2        0           
3      Level 1a       1   
4      Level 1b       1 
5      Level 1a1      3      

I have found a similar question to mine on the site but when I attempted it's solution I got the following on repeat infinetly:

Code:

function makeList($par_id = 0) {
    //your sql code here
    $result = mysql_query("SELECT * FROM pB_test WHERE parentId = $par_id");
    $pages = mysql_fetch_array( $result );

    if (count($pages)) {
        echo '<ul>';
        foreach ($pages as $page) {
            echo '<li>', $page['description'];
                makeList($page['parentId']);
                echo '</li>';
        }
        echo '</ul>';
    }
}

makeList();

Output:

1
3
5
5
l
l
3
5
5
l
l
3
5
5
l
l
3
5
5
l
l

Does anyone know how to fix this and what the issue is exactly? Cheers

2
MySQL does not support recursive JOINs, which is what you really need, however if you know you only have three levels and will only ever have three levels, you can just left join the table onto itself three timesDaveRandom

2 Answers

6
votes

Do this recursivly:

function printChildQuestions($parentid) {
  $sql="SELECT * FROM pB_test WHERE parentID=$parentid";
  $result=mysql_query($sql);
  $i=0;
  while (true) {
    $row=mysql_fetch_array($result);
    if (!$row) break;
    if ($i==0) echo "<ul>";
    $i=1;
    echo '<li>'.$row['id'].'&nbsp;'.$row['description'].'&nbsp;'.$row['parentId'].'</li>';
    printChildQuestions($row['id']);
  }
  if ($i>0) echo '</ul>';
}

printChildQuestions(0);
8
votes

it's not good to call mysql server and fetch result each time

what if you have over 100 rows? or 200+

use this to query only once:

$result = mysql_query("SELECT * FROM test");
$arrs = array();

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    $arrs[] = $row;
}

function build_tree($arrs, $parent_id=0, $level=0) {
    foreach ($arrs as $arr) {
        if ($arr['parent_id'] == $parent_id) {
            echo str_repeat("-", $level)." ".$arr['name']."<br />";
            build_tree($arrs, $arr['id'], $level+1);
        }
    }
}

build_tree($arrs);

common example for table

  id    name    parent_id