How to recursively build a <select> with unknown tree depth
php, recursion, tree
Solution
Pass a parameter to count the iteration like `$pass`
function toUL ($arr, $pass = 0) {
$html = '<ul>' . PHP_EOL;
foreach ( $arr as $v ) {
$html.= '<li>';
$html .= str_repeat("--", $pass); // use the $pass value to create the --
$html .= $v['name'] . '</li>' . PHP_EOL;
if ( array_key_exists('children', $v) ) {
$html.= toUL($v['children'], $pass+1);
}
}
$html.= '</ul>' . PHP_EOL;
return $html;
}
Problem
I have a MySQL table with a tree data structure. The fields are `_id`, `name` and `parentId`. When the record hasn't a parent, `parentId` defaults as 0. This way I can build an array and then recursively print each record. The builded array looks like this: ``` Array ( [1] => Array ( [parentId] => 0 [name] => Countries [_id] => 1 [children] => Array ( [2] => Array ( [parentId] => 1 [name] => America [_id] => 2 [children] => Array ( [3] => Array ( [parentId] => 2 [name] => Canada [_id] => 3 [children] => Array ( [4] => Array ( [parentId] => 3 [name] => Ottawa [_id] => 4 ) ) ) ) ) [5] => Array ( [parentId] => 1 [name] => Asia [_id] => 5 ) [6] => Array ( [parentId] => 1 [name] => Europe [_id] => 6 [children] => Array ( [7] => Array ( [parentId] => 6 [name] => Italy [_id] => 7 ) [11] => Array ( [parentId] => 6 [name] => Germany [_id] => 11 ) [12] => Array ( [parentId] => 6 [name] => France [_id] => 12 ) ) ) [8] => Array ( [parentId] => 1 [name] => Oceania [_id] => 8 ) ) ) ) ``` Printing an unordered list `<ul>` is very simple with recursion. Here's the function I use: ``` function toUL ($arr) { $html = '<ul>' . PHP_EOL; foreach ( $arr as $v ) { $html.= '<li>' . $v['name'] . '</li>' . PHP_EOL; if ( array_key_exists('children', $v) ) { $html.= toUL($v['children']); } } $html.= '</ul>' . PHP_EOL; return $html; } ``` But I'm stuck at printing a `<select>` in a tree-structured way: ``` Countries -- America ---- Canada ------ Ottawa -- Asia -- Europe ---- Italy ---- Germany ---- France -- Oceania ``` I thought to print `--` as many times as the element's depth, but I don't know how to calculate the depth. My question is: is it possible to build a `<select>` without knowing the depth? Thank you in advance.