这个PHP递归函数有什么问题?

时间:2012-11-30 20:46:54

标签: php

我有一个包含以下数据的数据库表:

categoryId    categoryName    parentCategory
men           Men             root
women         Women           root
shoes         Shoes           root
mensshirts    Men's Shirts    men
menspants     Men's Pants     men
mensjeans     Men's Jeans     men
mensvests     Men's Vests     men
womensshirts  Women's Shirts  women
womenpants    Women's Pants   women

我正在使用递归函数打印出分层菜单。代码如下。

function display_children($parent) {
    global $connect;
    $query = "SELECT categoryId, categoryName FROM categories WHERE parentCategory='$parent'";
    $result = mysqli_query($connect,$query);

    if ( $result === false ) {
       printf("Query Error: %s\n", mysqli_error($connect));
       exit();
    }

    echo "<ul>";
    while ($row = mysqli_fetch_assoc($result)) {
       extract($row);
       echo "<li>".$categoryName."</li>";
       display_children($categoryId);   
    }
    echo "</ul>";

    mysqli_close($connect);
}

display_children('root');

结果,我在屏幕上打印出来了:

  • 男性
    • 男士衬衫
    • 男士裤子
    • 男士牛仔裤
    • 男士背心
  • 女性

递归函数不会打印出其余的子序列,我不知道为什么。我的测试/调试已经确认,在将mensvests作为categoryId传递到函数中之后,传递的下一个categoryId是women,它应该找到最后一个子类。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

老实说,你应该重新评估你对此的处理方法并废弃该功能。在递归函数中运行查询只是在寻找麻烦。如果你有50个不同的分类分支,你真的想要运行50个左右的查询,只是为了显示它们吗?您应该阅读有关使用MySQL管理分层数据的this article。通过使用正确的方法,您可以运行一个查询而不是多个查询。适用于您的方案的文章中的示例:

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id

值得注意的是,该文章实际上建议遵循嵌套集模型。

答案 1 :(得分:0)

您正在关闭函数末尾的数据库连接。对于递归迭代,在第一次递归进入完全深度后,您将无法使用连接。

更好的方法是将数据库连接作为参数传递给函数

function display_children($parent, $db) {
    // when you recurse call
    display_children($categoryId, $db);
}

display_children('root', $connect);
mysqli_close($connect);

答案 2 :(得分:0)

我认为你的问题在于你使用“exit”而不是“return”语句。 此外,您关闭与

的连接
mysqli_close($connect);

这不是你想要做的。 退出停止你的整个程序,而返回(即使你没有给出值返回)只是出去功能。

然后你必须改变你的算法,这完全不是正确的方法。

对我来说,最好的方法是首先获取所有结果(使用mysqli_fetch_all),然后按照允许您按正确顺序显示数组的方式对数组进行排序。