2012-11-30 138 views
1

我有以下數據的數據庫表:這個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'); 

其結果是,我得到這個打印屏幕上:

  • 男性
    • 男式襯衫
    • 男裝褲
    • 男式牛仔褲
    • 男士背心
  • 女性

的遞歸函數不打印出來的subcats的休息,我不知道爲什麼。我的測試/調試已經證實,在mensvests作爲categoryId傳入函數之後,下一個傳遞給categoryId的是women,它應該定位最後一個subcats。有任何想法嗎?

+0

你需要逃避你的變量,否則你很容易出現安全風險和黑客行爲。 –

+0

您是否嘗試過調試? – SergeS

+1

爲什麼使用'extract()'的時候可以使用'$ row ['categoryName']'? – Spudley

回答

0

您正在關閉功能末尾的數據庫連接。對於遞歸迭代,在第一次遞歸達到全面深度後,將不會有連接使用。

一個更好的方法是通過您的DB連接到函數作爲參數

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

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

邁克 - 你是對的。通過使用上述方法,菜單正確打印。感謝您的幫助! – Leann

0

我覺得你的問題是你使用的「退出」,而不是「回報」的聲明的事實。 此外,您關閉與

mysqli_close($connect); 

您的連接,是不是你想要做什麼。 退出停止你的整個程序,而返回(即使你沒有給tu值返回)只是出去的功能。

然後,你必須改變你的算法,這是不是正確的方法來做到這一點。

對我來說,最好的辦法是首先獲取所有結果(使用mysqli_fetch_all),然後按允許以正確順序顯示數組的方式對數組進行排序。

1

老實說,你應該重新評估你的方法,並廢除功能。在遞歸函數中運行查詢只是在尋找麻煩。如果你有50個不同類別的分支,你真的想運行50個左右的查詢,只是爲了顯示它們嗎?您應該閱讀this article關於使用MySQL管理分層數據。通過使用正確的方法,您可以運行一個查詢而不是多個查詢。從文章的例子,將適用於您的情況:

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 

值得一提的是,文章竟建議以下一組嵌套模型。

+0

韋恩 - 謝謝你的這篇文章!我仍在學習,這似乎是一個更清潔的方式。 – Leann

+1

+1在這裏。雖然我提供瞭解決當前問題的答案。這個答案在指出長期問題方面做得很好。在這裏,您應該可以簡單地查詢數據庫一次,然後遍歷結果,大大減少數據庫上的查詢數量。 –