Recursive function help?

Hi,

I am having trouble with a recursive function to produce a nested HTML list. I’ve tried a bunch of things and have come close, but alas…no success. I was hoping someone here could help me.

I have an array of Message objects. Each Message object can have multiple children but does not necessarily have any. I want to make a nested list of message titles.

Message methods:

// returns true if it has any children, false otherwise
$message->hasChildren()
// returns a message object of the next child. $message now has one less child.
$message->nextChild() 
// display the message title
$message->title

How to make a nested list:

<ul>
  <li>
    Parent 1
    <ul>
      <li>
        Child 1 of Parent 1
        <ul>
          <li>Grandchild 1 of Parent 1</li>
          <li>Grandchild 2 of Parent 1</li>
        </ul>
      </li>
      <li>
        Child 2 of Parent 1
      </li>
    </ul>
  </li>
  <li>
    Parent 2
  </li>
</ul>

Thanks!

EDIT:

This actually works, but it constructs a separate list for each parent. Not exactly what I wanted but it will probably do.

function threadHTML($parent) {
  $html  = '<ul style="margin-top: 0; margin-bottom: 0;">';
  $html .= '<li>';
  $html .= $parent->title;
  while($parent->hasChildren()) {
    $child = $parent->nextChild();
    $html .= threadHTML($child);
  }
  $html .= '</li>';
  $html .= '</ul>';
  return $html;
} 

$html = '';
foreach($messages as $message) {
  $html .= threadHTML($message);
}
echo $html;

This is untested, but it should help you out:


function threadHTML($parent) {
    $html  = '<ul style="margin-top: 0; margin-bottom: 0;">';
    $html .= '<li>' . $parent->title . '</li>';
    
    if($parent->hasChildren()) {
        threadHTML($parent->nextChild());
    }
    $html .= '</ul>';
    
    return $html;
}

I’m not sure how you are identifying when you have more than one “title” but it shouldn’t be to hard to figure that out on your own.

The reason why I didn’t use a return on the function is because I needed it to bubble back up in order to close out the <ul> element correctly and I’m not looking for a value.

If you’re looking for a way to traverse the DOM, look no further: http://us2.php.net/manual/en/book.dom.php

HI chatmasta,
I think you have to have return while you call a recursive function and there should be a stopping condition.


return threadHTML($child)

example:


function factorial($number) {
    //stopping condition.    
    if ($number == 0){ 
        //return
        return 1;
    }       
        return $number * factorial($number - 1);
}
    print factorial(3);