递归循环返回500内部服务器错误

时间:2016-11-01 11:28:52

标签: php recursion

在循环中调用递归时出现500内部服务器错误!只有我得到500错误。

当我删除循环中的recusive时,一切正常:

检查我的代码:

   public function getRecrusiveReferals($userID)
    {
        $sql = "SELECT user_id, username, refered_by FROM users WHERE refered_by = ?";

        $referals = $this->db->query($sql, $userID);

        $list = $this->buildReferalsTree($referals->result_array());

        return $list;
    }


    private function buildReferalsTree(array $referals, $parentID = 0)
    {
        $data = array();

        foreach ($referals as $item)
        {
            if($item['refered_by'])
            {
                $children = $this->buildReferalsTree($referals, $parentID);

                if($children) {
                    $item['children'] = array();
                }

            }
            $data[] = $item;

        }

        return $data;
    }

3 个答案:

答案 0 :(得分:0)

当递归达到PHP为递归深度设置的限制时,您的代码具有无限递归循环,导致您的脚本被PHP杀死。

使用相同的参数集一次又一次地调用此代码:

 $children = $this->buildReferalsTree($referals, $parentID);

对于要终止的递归函数,应该有一个条件应该定义递归何时结束,我在你的代码中没有看到。

答案 1 :(得分:0)

您需要为父参数传递一个新值,而不是一遍又一遍。像这样:

$children = $this->buildReferalsTree($referals, $item['user_id']);

然后在循环中,您还需要按父ID过滤:

if($item['refered_by'] = $parentID)

...所以你只会链接那个ID为“孩子”的项目。

此外,您的原始调用还应指定parentID,因为您只选择表格的特定referred_by子集:

$list = $this->buildReferalsTree($referals->result_array(), $userID);

但是,这会产生无趣的结果,因为您只选择了具有相同 referred_by值的记录,因此构建树的次数不多。相反,您可以从该表中选择所有记录,然后仍然将$userID传递给buildReferalsTree,然后将有所有其他记录用于跟踪推荐链。所以这是选择所有记录的代码:

$sql = "SELECT user_id, username, refered_by FROM users";
$referals = $this->db->query($sql);

最后,内部if块中也存在错误,您当前将空数组分配给$item['children']。您应该改为从递归调用中分配结果,如下所示:

if($children) {
    $item['children'] = $children;
}

将这一切放在一起,代码看起来像这样:

public function getRecrusiveReferals($userID) {
    $sql = "SELECT user_id, username, refered_by FROM users";
    $referals = $this->db->query($sql);
    $list = $this->buildReferalsTree($referals->result_array(), $userID);
    return $list;
}

private function buildReferalsTree(array $referals, $parentID = 0) {
    $data = array();
    foreach ($referals as $item) {
        if ($item['refered_by'] == $parentID) {
            $children = $this->buildReferalsTree($referals, $item['user_id']);
            if($children) {
                $item['children'] = $children;
            }
        }
        $data[] = $item;
    }
    return $data;
}

如果您的数据在推介方面具有周期,则仍然可以提供无限递归。鉴于推荐的意义,情况应该不是这样。

答案 2 :(得分:0)

正如Jay Rajput所说,你在那里得到了无限的递归。我认为这个电话

$children = $this->buildReferalsTree($referals, $parentID);

不应该传递$referals,而是传递另一个基于' refered_by' $item的元素。 所以基本上你需要创建另一个私有方法,它提取新的$referals。 您必须仍然知道此代码不会是错误的,如果两个项目相互引用,您仍将以无限递归结束。

您尝试完成的工作非常具有挑战性,尤其是当您使用关系数据库时。你肯定想看看嵌套的套装'关系数据库中的概念。