I have a MySQL table with a tree data structure. The fields are _id
, name
and parentId
. When the record hasn\'t a parent, parent
Your problem is already solved within the SPL. The RecursiveIteratorIteratorDocs has the information about one's item's depth:
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), SELF_FIRST);
foreach ($it as $key => $element)
{
if ($key !== 'name') continue;
$inset = str_repeat('--', $it->getDepth());
printf('<option>%s %s</option>', $inset, $element);
}
My final solution (thanks to Starx and varan):
function toSelect ($arr, $depth=0) {
$html = '';
foreach ( $arr as $v ) {
$html.= '<option value="' . $v['_id'] . '">';
$html.= str_repeat('--', $depth);
$html.= $v['name'] . '</option>' . PHP_EOL;
if ( array_key_exists('children', $v) ) {
$html.= toSelect($v['children'], $depth+1);
}
}
return $html;
}
echo '<select>';
echo toSelect($array);
echo '</select>';
Even the RecursiveIteratorIterator
solution is good (thanks hakre).
You could pass the length to the function and increment it when you call recursively and then use the variable $length
to determine the depth
function toUL ($arr, $length = 0) {
$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'], $length++);
}
}
$html.= '</ul>' . PHP_EOL;
return $html;
}
This is what i do usually to keep track of recursion depth and it usually get the job done
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;
}
you can use optgroup as an iterator. For Example:
<select name="list">
<option value=1>1st option</option>
<optgroup>
<option value=10>1st on 1st group</option>
</optgroup>
</select>
if you want php, you can try this one:
<?PHP
function toSELECT($arr,$depth=0)
{
$html="";
if(is_array($arr))
{
$html.=($depth==0)?"<select name='html'>\n":"";
foreach ($arr as $key=>$value)
{
if(is_array($arr[$key]))
{
$html.=str_repeat("\t",$depth)."<optgroup>\n";
$html.=str_repeat("\t",$depth).toHTML($arr[$key],$depth+1);
$html.=str_repeat("\t",$depth)."</optgroup>\n";
}
else
{
$html.=str_repeat("\t",$depth)."<option value='".$value."'>".$key."</option>\n";
}
}
$html.=($depth==0)?"</select>\n":"";
}
return $html;
}
?>
function toSelect($arr, $depth = 0) {
$html = '';
foreach ( $arr as $v ) {
$html.= '<option>' . str_repeat("--", $depth) . $v['name'] . '</option>' . PHP_EOL;
if ( array_key_exists('children', $v) ) {
$html.= toSelect($v['children'], $depth++);
}
}
return $html;
}