递归函数不会在PHP中返回预期值

时间:2014-01-10 17:07:00

标签: php function recursion null return

我正在尝试编写的递归函数出现问题。在这里你可以看到我的代码:

function getParents($individualInfo) {

        $individualid = '';

        if(is_array($individualInfo)) {
            foreach($individualInfo as $key => $value) {
                if(is_array($individualInfo[$key])) {
                    return $this->getParents($individualInfo[$key]);
                }
                else {
                    if ($key == 'individual_id') {
                        $individualid = $individualInfo[$key];
                    }
                }
            }
        }
        else {
            $individualid = $individualInfo; 
        }
        $q = "SELECT i.individual_id, i.fname, i.lname, i.birth_date, i.death_date, i.gender, 
                i.biography, i.avatar, i.individual_username, r.relationship_individual 
                FROM ".TBL_RELATIONSHIPS." AS r, ".TBL_INDIVIDUALS." AS i
                WHERE r.relationship_individual = '$individualid' 
                AND r.individual = i.individual_id
                AND (r.role = '2')
                LIMIT 2";

        $result = $this->database->query($q);

        if ($result === false) {
            $result .= die(mysql_error());
            return;
        }

        $num_rows = mysql_num_rows($result);
        $tmp_array = array();


        if ($num_rows > 0) {
            while ($row = mysql_fetch_assoc($result)) {
                $tmp_array[] = $row;
            }
            foreach ($tmp_array as $tmp_parents) {
                $tmp_parents['individual_id'] = $this->database->cleanOutput($tmp_parents['individual_id']);
                $tmp_parents['fname'] = $this->database->cleanOutput($tmp_parents['fname']);
                $tmp_parents['lname'] = $this->database->cleanOutput($tmp_parents['lname']);
                $tmp_parents['birth_date'] = $this->database->cleanOutput($tmp_parents['birth_date']);
                $tmp_parents['death_date'] = $this->database->cleanOutput($tmp_parents['death_date']);
                $tmp_parents['gender'] = $this->database->cleanOutput($tmp_parents['gender']);
                $tmp_parents['biography'] = $this->database->cleanOutput($tmp_parents['biography']);
                $tmp_parents['avatar'] = $this->database->cleanOutput($tmp_parents['avatar']);
                $tmp_parents['individual_username'] = $this->database->cleanOutput($tmp_parents['individual_username']);
                $tmp_parents['relationship_individual'] = $this->database->cleanOutput($tmp_parents['relationship_individual']);
                // father
                if (!isset($parents[0]) && $tmp_parents['gender'] == 'Male') {
                    $parents[0] = $tmp_parents;
                }
                // mother
                else {
                    $parents[1] = $tmp_parents;
                }
            }
            return $parents;
        }

    }

$this->getParents($this->getParents($individualid));

如果只传递了id,则输出如下所示,例如160:

Array ( [0] => Array ( [individual_id] => 161 [fname] => John [lname] => Doe [birth_date] => [death_date] => [gender] => Male [biography] => [avatar] => [individual_username] => [relationship_individual] => 160 ) [1] => Array ( [individual_id] => 162 [fname] => Jane [lname] => Doe [birth_date] => [death_date] => [gender] => Female [biography] => [avatar] => [individual_username] => [relationship_individual] => 160 ) )

如果我将上面发布的数组传递给函数,我想得到这些结果:

Array ( [0] => Array ( [individual_id] => 163 [fname] => Sr. John [lname] => Doe [birth_date] => [death_date] => [gender] => Male [biography] => [avatar] => [individual_username] => [relationship_individual] => 161 ) [1] => Array ( [individual_id] => 164 [fname] => Sr. Jane [lname] => Doe [birth_date] => [death_date] => [gender] => Female [biography] => [avatar] => [individual_username] => [relationship_individual] => 161 ) )
Array ( [0] => Array ( [individual_id] => 165 [fname] => Sr. John [lname] => Roe [birth_date] => [death_date] => [gender] => Male [biography] => [avatar] => [individual_username] => [relationship_individual] => 162 ) [1] => Array ( [individual_id] => 166 [fname] => Sr. Jane [lname] => Roe [birth_date] => [death_date] => [gender] => Female [biography] => [avatar] => [individual_username] => [relationship_individual] => 162 ) )

上述功能应该帮助我找到任何特定个体或一系列个体的父母。例如,如果传递了包含父项的数组,则返回祖父母的所有数据。现在,该函数不会返回所有结果,因为我在第一个foreach循环中使用了return语句,而函数只能返回一次。但是,如果我不使用return,则返回null,因为此时$ individualid是一个空字符串。显示信息的功能如下所示:

function displayParents($parentsInfo)   {

        foreach ($parentsInfo as $parents) {
            // father
            if (isset($parents[0])) {
                $type = 'father'; 
                $individualid = $parents[0]['individual_id'];
                $name = $parents[0]['fname'].' '.$parents[0]['lname'];
                $bdate = $parents[0]['birth_date'];
                $ddate = $parents[0]['death_date'];
                $gender = $parents[0]['gender'];
                $bio = $parents[0]['biography'];
                $avatar = $parents[0]['avatar'];
                $username = $parents[0]['individual_username'];
                $relationshipid = $parents[0]['relationship_individual'];
                $this->displayLeaf($type, $individualid, $name, $gender, $bdate, $ddate, $bio, $avatar, $username, $relationshipid);
            }
            else {
                $type = 'emptyFather';
                $this->displayLeaf($type, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
            }
            // mother
            if (isset($parents[1])) {
                $type = 'mother'; 
                $individualid = $parents[1]['individual_id'];
                $name = $parents[1]['fname'].' '.$parents[1]['lname'];
                $bdate = $parents[1]['birth_date'];
                $ddate = $parents[1]['death_date'];
                $gender = $parents[1]['gender'];
                $bio = $parents[1]['biography'];
                $avatar = $parents[1]['avatar'];
                $username = $parents[1]['individual_username'];
                $relationshipid = (isset($parents[0]) ? $parents[0]['individual_id'] : $parents[1]['relationship_individual']);
                $this->displayLeaf($type, $individualid, $name, $gender, $bdate, $ddate, $bio, $avatar, $username, $relationshipid);
            }
            else {
                $type = 'emptyMother';
                $this->displayLeaf($type, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
            }
        }
    }

我试图寻找我的问题的答案,但我找不到任何解决方案,因为我真的很陌生。有关如何更改功能以使其完全符合我需要的任何建议吗?

1 个答案:

答案 0 :(得分:0)

你真的需要递归吗?

我并不是100%清楚你期望什么样的输出,如果它只是输入中所有父母的平面阵列,那么你可以很容易地做到。

function getParents($individualInfo) {
    if ( is_integer($individualInfo)) { $individualInfo = array('individual_id' => $individualInfo); }
    if ( isset($individualInfo['individual_id'])) { $individualInfo = array($individualInfo); }
    /* input is now consistently an array of associative arrays that should have a key 'individual_id' */

    $ids = array();
    foreach ($individualInfo as $individual)
    {
        if (!empty($individual['individual_id']) && is_integer($individual['individual_id']) )
        {
            $ids[$individual['individual_id']] = true; 
            /* I'm doing this instead of simply adding the id to the array
               so I can get just the unique ids from the array_keys later*/
        }
    }

    $idsstring = implode(',', array_keys($ids));
    $maxparents = 2*count($ids); /* Well, assuming nuclear families */

    /* there might not be any ids for some reason (like bad input) */
    if (empty($idsstring))
    {
        return array();
    }

    /* we've checked that all ids are integers, so there is little risk of SQL-injection 
    *  With `r.relationship_individual IN ($idsstring)` we can search for all parents of 
    *  all individuals at once.
    */
    $q = "SELECT i.individual_id, i.fname, i.lname, i.birth_date, i.death_date, i.gender, 
            i.biography, i.avatar, i.individual_username, r.relationship_individual 
            FROM ".TBL_RELATIONSHIPS." AS r, ".TBL_INDIVIDUALS." AS i
            WHERE r.relationship_individual IN ($idsstring)
            AND r.individual = i.individual_id
            AND (r.role = '2')
            LIMIT $maxparents";

    $result = $this->database->query($q);

    if ($result === false) {
        $result .= die(mysql_error());
        return;
    }

    $num_rows = mysql_num_rows($result);
    $tmp_array = array();
    $parents = array();
    if ($num_rows > 0) {
        while ($row = mysql_fetch_assoc($result)) {
            $tmp_array[] = $row;
        }
        foreach ($tmp_array as $tmp_parents) {
            foreach($tmp_parents as $key => $value){
                $tmp_parents[$key] = $this->database->cleanOutput($value);
            }
            $parents[] = $tmp_parents;
        }
    }
    return $parents;
}

另一方面,如果你想建立一个父母父母的父树,那么递归可能是有序的。 (尽管从数据库中获取父母的信息仍然是最好的避免。一次查询数据库效率更高。)现在,如果是这样的话,请允许我。