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:
- A variable or a parameter to hold the current position, which is
$r
in your code. You got this one right. - 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 callrecursive()
. A simple solution is to declare it asglobal
inside the function. - An
if
statement that checks the stop condition, which you don't have. Instead, you have ado-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.