简体   繁体   中英

How can I implement multi threaded recursion in PHP?

I have a category tree in XML like

<cat name='cat_1' id='1'>

 <cat name='cat_2' id='2'>
   <cat name='cat_3' id='3'>

   </cat>
 </cat>

 <cat name='cat_4' id='4'>
   <cat name='cat_5' id='5'>

      <cat name='cat_6' id='6'>
        <cat name='cat_7' id='7'>

        </cat>
      </cat>
  </cat>  
 </cat>

</cat>

now I want to implement code such that I can travers this tree an find categories ids by the name ie If input is cat_6 than result should be 6;

What I have done

$xmlCatTree // is my simple xml object

class MyClass{   
 public function traverseForId($cat_name , $xmlCatTree )
      {

        if($xmlCatTree->attributes()->name == $cate_name)
            {
              return $xmlCatTree->attributes()->id;
            }
        if(count($item->children())>0){
        foreach($item->children() as $child)
        {
             return $this->traverseForId($cat_name,$child);
        } } 

      } 

}

It works perfectly for single branch ie child nodes of cat_2 will have correct results but if I search for cat_7 nothing will return. I thing It happens due to branched recursion. I want to know how to cop this.

It seems, that you are using SimpleXML , thus I recommend to directly query the tree.

foreach ($xmlCatTree->xpath('//cat[@name=' . $cat_name . ']') as $node)
  return $node->attributes()->id;
}
return null;

This is even more elegant, because it directly reflects, what you are trying to achieve: Give me all the nodes with attribute "name" with the value " $cat_name ".

Or (because it seems, that the ID is already part of the category name ;))

list($unusedThingy, $id) = array_pad(explode('_', $cat_name, 2), 2, null);
return $id;

But I guess thats not really, what you are looking for ;)

Your function check only first child, try to use my code:

public function traverseForId($cat_name, $xmlCatTree)
{
    if ($xmlCatTree->attributes()->name == $cat_name)
        return $xmlCatTree->attributes()->id;

    foreach ($xmlCatTree->children() as $child) {
        $res = $this->traverseForId($cat_name, $child);
        if($res)
            return $res;
    }
    return NULL;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM