Search code examples
phpxmlfunctionloopschildren

PHP - How do I make a function wait and return another functions value


So I have some XML I need to loop through children to find a childs value. The problem is the actual looping. The way I know of is making a function, and if there is a child, use the same function and loop through the children - and again and so fourth.

My problem is that it doesn't seem as if the function is waiting for the "child function" to finish before returning my value.

Is there a better way of doing this? I know there are callbacks but I'm unsure how I would implement it here

Example XML

<?xml version="1.0" standalone="yes"?>
<pages>
    <page>
        <title>Parent Page1</title>
        <id>0</id>
        <children>
            <page>
                <title>Child Page1</title>
                <id>1</id>
                <children/>
            </page>
        </children>
    </page>
    <page>
        <title>Parent Page2</title>
        <id>2</id>
        <children>
            <page>
                <title>Child Page2</title>
                <id>3</id>
                <children/>
            </page>
        </children>
    </page>
</pages>

Example PHP

$page = "Child Page2";
echo "The ID of " . $page . " is " . a($page);

function a ($title) {
    $xml = simplexml_load_file("pages.xml") or die("Failed.");
    return b ($xml[0], $title);
}

function b ($pages, $title) {
    $val;
    foreach ($pages as $page) {
        if($page->title == $title) {
            $val = $page->id;
            break;
        } else if ($page->children->children() > 0){
            $val = b($page->children->children(), $title);
        }
    }
    return $val;
}

Is outputting: The ID of Child Page2 is

Now I know the XML isn't perfect in this example but it's only a placeholder so you understand what I'm trying to do. I'm using SimpleXML on the XML if that helps in any way

Solution

The problem was that if b(); returned in the first branch, but still needed to check other branches of children, the whole thing returned null or simply nothing at all.

My solution lower down works, but went with Swayze's answer because it's shorter and more effective (Saves saving variables)


Solution

  • function b ($pages, $title){
        foreach ($pages as $page){
            if($page->title == $title){
                // returns id regardless of how many loops in you are 
                return $page->id;}
            else if ($page->children->children() > 0){
                // call function if it has children
                return b ($page->children->children(), $title);}}
        // if nothing is found
        return 'no results';}
    

    This is the simplest way providing there can only be one instance of each title..

    If i have misunderstood you and there is the chance that there can be more than one result for each search than this method will only return the id of the first match it finds.