PHP: Return an array from recursive function

SimpleXMLElement is not an array. You could convert it to an array, but PHP offers an iterator specifically for this case, SimpleXMLIterator.

Since you have a recursive structure, my suggestion is to flatten it with RecursiveIteratorIterator. Assuming your data is in a variable called $xml, your solution might look something like this:

$xmlIterator  = new SimpleXMLIterator($xml->Ancestors);
$flatIterator = new RecursiveIteratorIterator($xmlIterator, RecursiveIteratorIterator::SELF_FIRST);

$breadcrumb = [];
foreach($flatIterator as $node) {
    $breadcrumb[] = $node['Name'];
}

$breadcrumb = array_reverse($breadcrumb);

To create a recursive function with an output, you need three things:

  1. A variable or a parameter to hold the current position, which is $r in your code. You got this one right.
  2. A variable or a parameter that holds the result, which you don't have. At first it appears to be $bread, but it is not holding any value because it is empty every time you call recursive(). A simple solution is to declare it as global inside the function.
  3. An if statement that checks the stop condition, which you don't have. Instead, you have a do-while loop in your code.

So, you have two mistakes there. Based on your code and modifying it as little as possible, this is the correct code:

$rec = $result->BrowseNodes->BrowseNode->Ancestors->BrowseNode;

$bread = array();
function recursive($r)
{
    global $bread;

    $bread[] = strval($r->BrowseNodeId);

    if(isset($r->Ancestors)){
        return recursive($r->Ancestors->BrowseNode);
    }else{
        return array_reverse($bread);
    }
}

print_r(recursive($rec));

There you go.

Update: I agree with @FlameStorm, global should be avoided if possible. I also received suggestion to use static instead, but it introduces a bug. Thus, I recommend avoiding static as well if you're not sure how to use it.

This is the improved code:

$rec = $result->BrowseNodes->BrowseNode->Ancestors->BrowseNode;

function recursive($r)
{
    if(isset($r->Ancestors))
        $bread = recursive($r->Ancestors->BrowseNode);

    $bread[] = strval($r->BrowseNodeId);
    return $bread;
}

print_r(recursive($rec));

The $bread variable outside the function is no longer needed. Also, neither global or static is used.

Tags:

Php

Recursion