2011-07-11 88 views
1

我想創建一個包含產品總計的遞歸菜單,但是我現在被卡住了,因爲我已經呈現了Topmenu,但是我無法找到另一種方式來做到這一點。帶產品計數的遞歸菜單

我不想使用很多的MySQL查詢,因爲它可以使我的網站非常緩慢。

我使用的代碼:

require 'db.php'; 

$result = mysql_query("SELECT COUNT(c.category_id) AS count, c. category_id, c.parent_id, cd.name, p.product_id FROM category c 
    LEFT JOIN category_description AS cd ON (cd.category_id=c.category_id) 
    LEFT JOIN product_to_category AS ptc ON (ptc.category_id=c.category_id) 
    LEFT JOIN product AS P ON (p.product_id=ptc.product_id) 
    GROUP BY c.category_id  
    ORDER BY c.parent_id,cd.name") or die (mysql_error()); 

$menuData = array('items' => array(), 'parents' => array()); 

while ($menuItem = mysql_fetch_assoc($result)) { 
    $menuData['items'][$menuItem['category_id']] = $menuItem; 
    $menuData['parents'][$menuItem['parent_id']][] = $menuItem['category_id']; 
} 

function buildMenu($parentId, $menuData) { 
    $html = ''; 
    if (isset($menuData['parents'][$parentId])) 
    { 
     $html = '<ul>'; 

     foreach ($menuData['parents'][$parentId] as $itemId) { 
      $iCount = ($menuData['items'][$itemId]['product_id'] != NULL) ? $menuData['items'][$itemId]['count'] : '0'; 

      $html .= '<li>' . $menuData['items'][$itemId]['name'] . ' (' . $iCount . ') '; 
      $html .= buildMenu($itemId, $menuData); 
      $html .= '</li>'; 
     } 

     $html .= '</ul>'; 
    } 
    return $html; 
} 
echo buildMenu(0, $menuData); 

預期的輸出:

Dell (1) 
--Computer(1) 
---DataCable(1) 
----Extra Sub (0) 

電流輸出:

Dell (0) 
--Computer(0) 
---DataCable(1) 
----Extra Sub (0) 

回答

0

我覺得你的查詢將返回錯誤的結果。在調用buildMenu()函數之前使用 print '<pre>';print_r($menuData);print '</pre>';並查看查詢是否返回正確的數據。

+0

我得到每個類別正確的計數,但我的問題是,它呈現TopCat第一,並從那裏下降。 所以,當我走下去,我永遠不會得到最高分類的數量。 我需要另一個遞歸函數來首先計算一切嗎? 或者這個問題的最佳做法是什麼? – DirkZz

0

我想這應該讓你更接近正確的方向:

foreach ($menuData['parents'][$parentId] as $itemId) { 
    $menu = buildMenu($itemId, $menuData); 
    $item = $menuData['items'][$itemId]; 
    $iCount = ($item['product_id'] != NULL) ? $item['count'] : '0'; 
    $menuData['items'][$parentId]['count'] += $iCount; 
    $html .= '<li>' . $item['name'] . ' (' . $iCount . ') '; 
    $html .= $menu 
    $html .= '</li>'; 
} 

通過重新排序,然後將當前項目的數量父項的數量,就可以確保當你輸出ICOUNT,它也將包括所有兒童的數量。

我還爲$menuData['items'][$itemId]使用了一個臨時變量。因爲你只對這個$ menuData進行三次數組查找,所以它可能不會更有效,但它更易於閱讀。