緣由以下:php
①我的對商城類商品篩選功能的實現比較好奇;html
②對商城中關於商品的數據表設計比較感興趣。(該功能涉及到與數據庫的交互,並且與數據庫中數據表的設計好壞有必定的聯繫);mysql
③多條件(屬性)篩選功能在現今的不少網站都須要用到,很普遍(如:通常商城網、團購網、房產網、信息分類網站等等)。算法
但願達到的目的是:sql
①可以對多條件篩選功能有一個初步的認識。(起碼本身作,也可以快速實現吧);數據庫
②對多條件篩選的實現中,數據庫該如何去設計纔會更優化和更合理些(參考前人的經驗);數組
③對多條件篩選中的一些策略或者是技巧,能有一個瞭解(會總結幾點)緩存
①京東商城的商品篩選功能(截圖):服務器
②蘇寧商城的商品篩選功能(截圖)cookie
③國美在線的商品篩選功能(截圖)
補充:其實,要對該功能的觀察,還必須對地址欄,也做一番思考的,我這裏就省略了,畢竟若是這樣分析,會更簡單一些。上面這些例子,只做一個引子吧。後續我會完善它的。
④ECSHOP的商品篩選功能實現,展現細節(截圖+文字)以下:
1)首先,我本地服務器,給本機安裝的ecshop演示網站,配了一個虛擬主機地址:爲 http://demo.ecshop.com
2)而後,我就經過該地址來訪問主頁,並查看屬於導航欄中「GSM手機」分類下的商品。以下:
訪問地址爲:http://demo.ecshop.com/category.php?id=3
結果頁面爲:
那麼,此時的訪問,會羅列出,屬於「GSM手機」分類下(即cat_id=3)的全部商品,由於目前尚未對商品進行多篩選。
若是我想查看品牌爲「諾基亞」的手機,那麼點擊「諾基亞」標籤便可:
訪問地址爲: http://demo.ecshop.com/category.php?id=3&brand=1&price_min=0&price_max=0
結果頁面爲:
若是我選擇了多條件搜索,看截圖:
結果頁面爲:
分析:從上面的地址欄的變化和截圖的變化,能夠初步看出ecshop的多條件搜索方法是怎麼樣的了。
猜測1:隨着用戶每一次點擊條件(屬性)進行商品篩選時,搜索地址欄會變化,爲何地址欄會變化,歸根結底,必定是每個商品的屬性的a標籤的超連接地址被改變了。並且是每點擊一次,都會隨着搜索條件的不一樣,而改變。
從而咱們知道,這個屬性的超連接,是動態生成的。ecshop後臺必定是做了大量的判斷過程,並最終爲每個商品屬性,生成一個超連接地址,以防止上一次的搜索條件丟失。
猜測2:商品的價格區間,是根據什麼來計算的呢?仍是人工後臺設置的,京東的商品價格區間,好像都是頗有規律的,和ecshop的價格區間,有比較大的區別。別管這麼多了,咱們仍是先研究ecshop的再說。
猜測3:參數 filter_attr=163.0.160.0 中的幾個數字,必定表明着下面:顏色、屏幕大小 、手機制式、外觀樣式屬性下,都選擇了哪一些值了。
----> 帶着這樣一些疑問,那咱們直接去研究一下ecshop是如何實現上面的多條件搜索功能啦。。。GO。。。
首先,咱們到ecshop的網站更目錄,找到category.php文件,打開它進行研究一下。
1.點擊這裏,查看所有代碼的分析過程。
1 <?php 2 /** 3 * 分析首頁 商品分類頁面category.php的實現方法 4 * ECSHOP 2.7.2 商品分類 5 */ 6 define('IN_ECS', true); 7 require(dirname(__FILE__) . '/includes/init.php'); 8 if ((DEBUG_MODE & 2) != 2) { 9 $smarty->caching = true; 10 } 11 12 //====> 請求地址欄:http://localhost/category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 13 //====> 1.獲取分類id 14 /* 得到請求的分類 ID */ 15 if (isset($_REQUEST['id'])) { 16 $cat_id = intval($_REQUEST['id']); 17 } 18 elseif (isset($_REQUEST['category'])) { 19 $cat_id = intval($_REQUEST['category']); 20 } else { 21 /* 若是分類ID爲0,則返回首頁 */ 22 ecs_header("Location: ./\n"); 23 exit; 24 } 25 26 //====> 2.首先獲取全部GET和POST中,可用於搜索的參數的值。 27 //====> 若沒有此參數,則說明,並無用此參數來搜索,默認要給它一個默認值。 28 /* 初始化分頁信息 */ 29 $page = isset($_REQUEST['page']) && intval($_REQUEST['page']) > 0 ? intval($_REQUEST['page']) : 1; 30 $size = isset($_CFG['page_size']) && intval($_CFG['page_size']) > 0 ? intval($_CFG['page_size']) : 10; 31 $brand = isset($_REQUEST['brand']) && intval($_REQUEST['brand']) > 0 ? intval($_REQUEST['brand']) : 0; 32 $price_max = isset($_REQUEST['price_max']) && intval($_REQUEST['price_max']) > 0 ? intval($_REQUEST['price_max']) : 0; 33 $price_min = isset($_REQUEST['price_min']) && intval($_REQUEST['price_min']) > 0 ? intval($_REQUEST['price_min']) : 0; 34 $filter_attr_str = isset($_REQUEST['filter_attr']) ? htmlspecialchars(trim($_REQUEST['filter_attr'])) : '0'; 35 $filter_attr_str = urldecode($filter_attr_str); 36 $filter_attr = empty($filter_attr_str) ? '' : explode('.', trim($filter_attr_str)); 37 38 /* 排序、顯示方式以及類型 */ 39 $default_display_type = $_CFG['show_order_type'] == '0' ? 'list' : ($_CFG['show_order_type'] == '1' ? 'grid' : 'text'); 40 $default_sort_order_method = $_CFG['sort_order_method'] == '0' ? 'DESC' : 'ASC'; 41 $default_sort_order_type = $_CFG['sort_order_type'] == '0' ? 'goods_id' : ($_CFG['sort_order_type'] == '1' ? 'shop_price' : 'last_update'); 42 43 $sort = (isset($_REQUEST['sort']) && in_array(trim(strtolower($_REQUEST['sort'])), array('goods_id', 'shop_price', 'last_update'))) ? trim($_REQUEST['sort']) : $default_sort_order_type; 44 $order = (isset($_REQUEST['order']) && in_array(trim(strtoupper($_REQUEST['order'])), array('ASC', 'DESC'))) ? trim($_REQUEST['order']) : $default_sort_order_method; 45 $display = (isset($_REQUEST['display']) && in_array(trim(strtolower($_REQUEST['display'])), array('list', 'grid', 'text'))) ? trim($_REQUEST['display']) : (isset($_COOKIE['ECS']['display']) ? $_COOKIE['ECS']['display'] : $default_display_type); 46 $display = in_array($display, array('list', 'grid', 'text')) ? $display : 'text'; 47 setcookie('ECS[display]', $display, gmtime() + 86400 * 7); 48 49 /* 頁面的緩存ID */ 50 $cache_id = sprintf('%X', crc32($cat_id . '-' . $display . '-' . $sort .'-' . $order .'-' . $page . '-' . $size . '-' . $_SESSION['user_rank'] . '-' . 51 $_CFG['lang'] .'-'. $brand. '-' . $price_max . '-' .$price_min . '-' . $filter_attr_str)); 52 53 /* 若是頁面沒有被緩存則從新獲取頁面的內容 */ 54 if (!$smarty->is_cached('category.dwt', $cache_id)) { 55 //====> 3.把該欄目下的全部子欄目id獲取,若是沒有子欄目,則是自身。 56 //===> TABLE:ecs_category 57 //====> RETURN:id=3 => g.cat_id IN ('3') 或 id=6 => g.cat_id IN ('6','8','9','11','7') 58 //====> 說明:ecshop的特色是,頂級欄目下也能夠添加商品,因此會把頂級欄目id也放在數組裏面 59 $children = get_children($cat_id); 60 61 //====> 4.得到該分類的相關信息。如:分類名稱、價格分級、篩選屬性、父id 62 //===> TABLE:ecs_category 63 //====> RETURN:Array ( [cat_name] => GSM手機 [keywords] => [cat_desc] => [style] => [grade] => 4 [filter_attr] => 185,189,173,178 [parent_id] => 1 ) 64 $cat = get_cat_info($cat_id); 65 66 //===> 5.若是有品牌篩選brand參數,那麼獲取出該品牌名稱 67 //===> TABLE:ecs_brand 68 //===> SQL:SELECT brand_name FROM `ecshop`.`ecs_brand` WHERE brand_id = '1' 69 //====> RETURN:諾基亞 70 /* 賦值固定內容 */ 71 if ($brand > 0) { 72 $sql = "SELECT brand_name FROM " .$GLOBALS['ecs']->table('brand'). " WHERE brand_id = '$brand'"; 73 $brand_name = $db->getOne($sql); 74 } else { 75 $brand_name = ''; 76 } 77 78 79 ///>>================開始---商品價格區間處理==================>>/// 80 //===> 6.獲取該分類cat的價格分級: 81 //===> ①若是價格分級=0,那麼獲取直接父類的價格分級。(Ⅰ若是父類價格也=0,那麼就是不用價格分級 ) 82 //===> ②若是價格分級!=0,那麼就是自身的價格分級。 83 //===> TABLE:ecs_category 84 //===> RETURN:$cat['grade']=4 85 /* 獲取價格分級 */ 86 if ($cat['grade'] == 0 && $cat['parent_id'] != 0) { // ==>若是價格分級爲空,可是它還有上級分類,那麼取直接上級的價格分級等數 87 $cat['grade'] = get_parent_grade($cat_id); //若是當前分類級別爲空,取最近的上級分類 88 } 89 90 //===> 7.對價格區間進行劃分。 ecshop的劃分方法,是根據算法來的,比較複雜。 91 //===> 若是價格分級>1,那麼就執行價格區間劃分 92 if ($cat['grade'] > 1) { 93 /* 須要價格分級 */ 94 95 /* 96 算法思路: 97 一、當分級大於1時,進行價格分級 98 二、取出該類下商品價格的最大值、最小值 99 三、根據商品價格的最大值來計算商品價格的分級數量級: 100 價格範圍(不含最大值) 分級數量級 101 0-0.1 0.001 102 0.1-1 0.01 103 1-10 0.1 104 10-100 1 105 100-1000 10 106 1000-10000 100 107 四、計算價格跨度: 108 取整((最大值-最小值) / (價格分級數) / 數量級) * 數量級 109 五、根據價格跨度計算價格範圍區間 110 六、查詢數據庫 111 112 可能存在問題: 113 一、 114 因爲價格跨度是由最大值、最小值計算出來的 115 而後再經過價格跨度來肯定顯示時的價格範圍區間 116 因此可能會存在價格分級數量不正確的問題 117 該問題沒有證實 118 二、 119 當價格=最大值時,分級會多出來,已被證實存在 120 */ 121 122 //===> 得到當前分類下商品價格的最大值、最小值 123 //===> 得到全部擴展分類屬於指定分類的全部商品ID ,其中goods_id = 16的商品的擴展屬於分類3 124 //===> TABLE:ecs_goods 和 ecs_goods_cat 125 //===> SQL:SELECT min(g.shop_price) AS min, max(g.shop_price) as max FROM `ecshop`.`ecs_goods` AS g WHERE (g.cat_id IN ('5') OR g.goods_id IN ('8','16') ) AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 126 //===> RETURN:Array ( [min] => 280.00 [max] => 5999.00 ) 127 $sql = "SELECT min(g.shop_price) AS min, max(g.shop_price) as max ". 128 " FROM " . $ecs->table('goods'). " AS g ". 129 " WHERE ($children OR " . get_extension_goods($children) . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '; 130 $row = $db->getRow($sql); 131 132 133 //===> 按照公式計算出最低價格和最高價格、以及價格跨度 134 //===============↓↓↓先不作討論=============== 135 // 取得價格分級最小單位級數,好比,千元商品最小以100爲級數 136 $price_grade = 0.0001; 137 for($i=-2; $i<= log10($row['max']); $i++) { 138 $price_grade *= 10; 139 } 140 141 //價格跨度 142 $dx = ceil(($row['max'] - $row['min']) / ($cat['grade']) / $price_grade) * $price_grade; 143 if($dx == 0) { 144 $dx = $price_grade; 145 } 146 147 for($i = 1; $row['min'] > $dx * $i; $i ++); 148 149 for($j = 1; $row['min'] > $dx * ($i-1) + $price_grade * $j; $j++); 150 $row['min'] = $dx * ($i-1) + $price_grade * ($j - 1); 151 152 for(; $row['max'] >= $dx * $i; $i ++); 153 $row['max'] = $dx * ($i) + $price_grade * ($j - 1); 154 155 //===>這裏打印最高價格和最低價格:$row=>Array ( [min] => 200 [max] => 6200 ) 156 //===>這裏打印價格跨度:$dx = 1500 157 158 //===============先不作討論↑↑↑==================// 159 160 161 //===> 根據商品的價格、價格區間的最低價格、以及價格跨度,計算該商品價格屬於哪個區間內。 162 //===> 獲取屬於該價格區間內的商品的數量、獲取sn則屬於哪個區間sn=0爲200-1700、sn=1爲1700-3200、sn=3爲4700-6200。 163 //===> 由於沒有商品價格屬於第二區間,則不存在sn=2,那麼3200-4700則沒有任何商品 164 //===> TABLE:ecs_goods 和 ecs_goods_cat 165 //===> SQL:SELECT (FLOOR((g.shop_price - 200) / 1500)) AS sn, COUNT(*) AS goods_num FROM `ecshop`.`ecs_goods` AS g WHERE (g.cat_id IN ('3') OR g.goods_id IN ('16') ) AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 GROUP BY sn 166 //===>RETURN:Array ( [0] => Array ( [sn] => 0 [goods_num] => 6 ) [1] => Array ( [sn] => 1 [goods_num] => 5 ) [2] => Array ( [sn] => 3 [goods_num] => 1 ) ) 167 $sql = "SELECT (FLOOR((g.shop_price - $row[min]) / $dx)) AS sn, COUNT(*) AS goods_num ". 168 " FROM " . $ecs->table('goods') . " AS g ". 169 " WHERE ($children OR " . get_extension_goods($children) . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. 170 " GROUP BY sn "; 171 $price_grade = $db->getAll($sql); 172 173 174 //===> 根據價格等級price_grade,計算真正的價格區間。 175 //===> 方法build_uri()重要:要爲每個價格區間,生成一個url超連接,以備前臺點擊搜索用 176 //===> 並根據價格參數,判斷該區間,是不是當前被搜索的區間 177 //===> 把價格區間,注入模板,供前臺使用 178 //===> RETURN:Array ( [0] => Array ( [sn] => 0 [goods_num] => 6 [start] => 0 [end] => 0 [price_range] => 所有 [url] => category.php?id=3&brand=1&price_min=0&price_max=0&filter_attr=163.216.160.186 [selected] => 0 ) [1] => Array ( [sn] => 1 [goods_num] => 6 [start] => 200 [end] => 1700 [price_range] => 200 - 1700 [formated_start] => ¥200元 [formated_end] => ¥1700元 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [2] => Array ( [sn] => 3 [goods_num] => 5 [start] => 1700 [end] => 3200 [price_range] => 1700 - 3200 [formated_start] => ¥1700元 [formated_end] => ¥3200元 [url] => category.php?id=3&brand=1&price_min=1700&price_max=3200&filter_attr=163.216.160.186 [selected] => 0 ) [3] => Array ( [goods_num] => 1 [start] => 4700 [end] => 6200 [price_range] => 4700 - 6200 [formated_start] => ¥4700元 [formated_end] => ¥6200元 [url] => category.php?id=3&brand=1&price_min=4700&price_max=6200&filter_attr=163.216.160.186 [selected] => 0 ) ) 179 foreach ($price_grade as $key=>$val) { 180 $temp_key = $key + 1; 181 $price_grade[$temp_key]['goods_num'] = $val['goods_num']; 182 $price_grade[$temp_key]['start'] = $row['min'] + round($dx * $val['sn']); 183 $price_grade[$temp_key]['end'] = $row['min'] + round($dx * ($val['sn'] + 1)); 184 $price_grade[$temp_key]['price_range'] = $price_grade[$temp_key]['start'] . ' - ' . $price_grade[$temp_key]['end']; 185 $price_grade[$temp_key]['formated_start'] = price_format($price_grade[$temp_key]['start']); 186 $price_grade[$temp_key]['formated_end'] = price_format($price_grade[$temp_key]['end']); 187 $price_grade[$temp_key]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>$price_grade[$temp_key]['start'], 'price_max'=> $price_grade[$temp_key]['end'], 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 188 /* 判斷價格區間是否被選中 */ 189 if (isset($_REQUEST['price_min']) && $price_grade[$temp_key]['start'] == $price_min && $price_grade[$temp_key]['end'] == $price_max) { 190 $price_grade[$temp_key]['selected'] = 1; 191 } 192 else { 193 $price_grade[$temp_key]['selected'] = 0; 194 } 195 } 196 //補充一個選擇所有的類型的數組 197 $price_grade[0]['start'] = 0; 198 $price_grade[0]['end'] = 0; 199 $price_grade[0]['price_range'] = $_LANG['all_attribute']; 200 $price_grade[0]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>0, 'price_max'=> 0, 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 201 $price_grade[0]['selected'] = empty($price_max) ? 1 : 0; 202 //把價格區間數組,注入模板文件 203 $smarty->assign('price_grade', $price_grade); 204 } 205 ///<<================結束---商品價格區間處理==================<</// 206 207 208 ///>>================開始---商品品牌處理==================>>/// 209 //====> ???db_create_in(array_unique(array_merge(array($cat_id), array_keys(cat_list($cat_id, 0, false))))) . ") 210 //===> 品牌篩選功能:把該欄目下(其中包括擴展分類下的商品),全部商品的品牌獲取,但不能重複。 211 //===> 品牌下有商品而且商品狀態正常,才能把該品牌取出。沒有商品的品牌不能取出 212 //===> TABLE:ecs_brand、ecs_goods 和 ecs_goods_cat 213 //===> SQL:SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num FROM `ecshop`.`ecs_brand`AS b, `ecshop`.`ecs_goods` AS g LEFT JOIN `ecshop`.`ecs_goods_cat` AS gc ON g.goods_id = gc.goods_id WHERE g.brand_id = b.brand_id AND (g.cat_id IN ('3') OR gc.cat_id IN ('3') ) AND b.is_show = 1 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 GROUP BY b.brand_id HAVING goods_num > 0 ORDER BY b.sort_order, b.brand_id ASC 214 //===> RETURN:Array ( [0] => Array ( [brand_id] => 1 [brand_name] => 諾基亞 [goods_num] => 3 ) [1] => Array ( [brand_id] => 2 [brand_name] => 摩托羅拉 [goods_num] => 1 ) [2] => Array ( [brand_id] => 3 [brand_name] => 多普達 [goods_num] => 1 ) [3] => Array ( [brand_id] => 4 [brand_name] => 飛利浦 [goods_num] => 2 ) [4] => Array ( [brand_id] => 5 [brand_name] => 夏新 [goods_num] => 1 ) [5] => Array ( [brand_id] => 6 [brand_name] => 三星 [goods_num] => 2 ) [6] => Array ( [brand_id] => 7 [brand_name] => 索愛 [goods_num] => 1 ) [7] => Array ( [brand_id] => 9 [brand_name] => 聯想 [goods_num] => 1 ) [8] => Array ( [brand_id] => 10 [brand_name] => 金立 [goods_num] => 1 ) ) 215 /* 品牌篩選 */ 216 $sql = "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ". 217 "FROM " . $GLOBALS['ecs']->table('brand') . "AS b, ". 218 $GLOBALS['ecs']->table('goods') . " AS g LEFT JOIN ". $GLOBALS['ecs']->table('goods_cat') . " AS gc ON g.goods_id = gc.goods_id " . 219 "WHERE g.brand_id = b.brand_id AND ($children OR " . 'gc.cat_id ' . db_create_in(array_unique(array_merge(array($cat_id), array_keys(cat_list($cat_id, 0, false))))) . ") AND b.is_show = 1 " . 220 " AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 ". 221 "GROUP BY b.brand_id HAVING goods_num > 0 ORDER BY b.sort_order, b.brand_id ASC"; 222 $brands = $GLOBALS['db']->getAll($sql); 223 224 //===> 把該分類下全部商品的品牌,組合成數組,給前臺調用 225 //===> 方法build_uri()重要:要爲每品牌,生成一個url超連接,以備前臺點擊搜索用 226 //===> 把數組注入模板文件 227 //====! 這樣一種組織數組的方式,有它的缺陷:就是說不可以把每個品牌下面的,商品的數量保存下來,同時也會有一些無用的數據,摻雜其中。 228 //RETURN:Array ( [0] => Array ( [brand_id] => 1 [brand_name] => 所有 [goods_num] => 3 [url] => category.php?id=3&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [1] => Array ( [brand_id] => 2 [brand_name] => 諾基亞 [goods_num] => 1 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [2] => Array ( [brand_id] => 3 [brand_name] => 摩托羅拉 [goods_num] => 1 [url] => category.php?id=3&brand=2&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [3] => Array ( [brand_id] => 4 [brand_name] => 多普達 [goods_num] => 2 [url] => category.php?id=3&brand=3&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [4] => Array ( [brand_id] => 5 [brand_name] => 飛利浦 [goods_num] => 1 [url] => category.php?id=3&brand=4&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [5] => Array ( [brand_id] => 6 [brand_name] => 夏新 [goods_num] => 2 [url] => category.php?id=3&brand=5&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [6] => Array ( [brand_id] => 7 [brand_name] => 三星 [goods_num] => 1 [url] => category.php?id=3&brand=6&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [7] => Array ( [brand_id] => 9 [brand_name] => 索愛 [goods_num] => 1 [url] => category.php?id=3&brand=7&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [8] => Array ( [brand_id] => 10 [brand_name] => 聯想 [goods_num] => 1 [url] => category.php?id=3&brand=9&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [9] => Array ( [brand_name] => 金立 [url] => category.php?id=3&brand=10&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) ) 229 foreach ($brands AS $key => $val) { 230 $temp_key = $key + 1; 231 $brands[$temp_key]['brand_name'] = $val['brand_name']; 232 $brands[$temp_key]['url'] = build_uri('category', array('cid' => $cat_id, 'bid' => $val['brand_id'], 'price_min'=>$price_min, 'price_max'=> $price_max, 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 233 /* 判斷品牌是否被選中 */ 234 if ($brand == $brands[$key]['brand_id']) { 235 $brands[$temp_key]['selected'] = 1; 236 } else { 237 $brands[$temp_key]['selected'] = 0; 238 } 239 } 240 //補充一個選擇所有品牌的數組 241 $brands[0]['brand_name'] = $_LANG['all_attribute']; 242 $brands[0]['url'] = build_uri('category', array('cid' => $cat_id, 'bid' => 0, 'price_min'=>$price_min, 'price_max'=> $price_max, 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 243 $brands[0]['selected'] = empty($brand) ? 1 : 0; 244 //把品牌數組注入模板 245 $smarty->assign('brands', $brands); 246 ///<<==================結束---商品品牌處理==================<</// 247 248 249 250 ///>>==================開始---商品屬性處理==================>>/// 251 /* 屬性篩選 */ 252 $ext = ''; //商品查詢條件擴展 253 if ($cat['filter_attr'] > 0) { 254 //===>須要篩選的屬性,是人工在後臺添加的,存放在ecs_category 表的中 filter_attr字段裏面,格式如:185,189,120,190 255 //===>RETURN:Array ( [0] => 185 [1] => 189 [2] => 173 [3] => 178 ) 256 $cat_filter_attr = explode(',', $cat['filter_attr']); //提取出此分類的篩選屬性 257 258 //===> 而後,對每個屬性(此屬性是主屬性,下面還有子屬性),循環進行操做 259 //===> ①獲取該屬性的屬性名 260 //===> ②獲取該屬性的全部子屬性(子屬性必須是有被商品在使用的,否則,不要將其顯示出來) 261 //===> 意義:由於該屬性涉及到搜索參數,若是該屬性下自己沒有商品,那麼就沒有顯示出來的意義了。 262 //===> RETURN: Array ( [0] => Array ( [attr_id] => 185 [goods_id] => 167 [attr_value] => 灰色 ) [1] => Array ( [attr_id] => 185 [goods_id] => 198 [attr_value] => 白色 ) [2] => Array ( [attr_id] => 185 [goods_id] => 197 [attr_value] => 金色 ) [3] => Array ( [attr_id] => 185 [goods_id] => 163 [attr_value] => 黑色 ) ) 263 $all_attr_list = array(); 264 foreach ($cat_filter_attr AS $key => $value) { 265 $sql = "SELECT a.attr_name FROM " . $ecs->table('attribute') . " AS a, " . $ecs->table('goods_attr') . " AS ga, " . $ecs->table('goods') . " AS g WHERE ($children OR " . get_extension_goods($children) . ") AND a.attr_id = ga.attr_id AND g.goods_id = ga.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND a.attr_id='$value'"; 266 if($temp_name = $db->getOne($sql)) { 267 //獲取該屬性名(主屬性) 268 $all_attr_list[$key]['filter_attr_name'] = $temp_name; 269 270 //獲取該屬性的全部子屬性(子屬性必須是有被商品在使用的,否則,不要將其顯示出來) 271 //RETURN: Array ( [0] => Array ( [attr_id] => 185 [goods_id] => 167 [attr_value] => 灰色 ) [1] => Array ( [attr_id] => 185 [goods_id] => 198 [attr_value] => 白色 ) [2] => Array ( [attr_id] => 185 [goods_id] => 197 [attr_value] => 金色 ) [3] => Array ( [attr_id] => 185 [goods_id] => 163 [attr_value] => 黑色 ) ) 272 $sql = "SELECT a.attr_id, MIN(a.goods_attr_id ) AS goods_id, a.attr_value AS attr_value FROM " . $ecs->table('goods_attr') . " AS a, " . $ecs->table('goods') . 273 " AS g" . 274 " WHERE ($children OR " . get_extension_goods($children) . ') AND g.goods_id = a.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. 275 " AND a.attr_id='$value' ". 276 " GROUP BY a.attr_value"; 277 $attr_list = $db->getAll($sql); 278 279 //若是後臺指定該分類下,用於搜索的屬性的組數,是跟地址欄中filter_attr=0.0.0.0 中0的個數是同樣的,並且順序都是同樣的 280 //第一個0,表示第一組屬性中,它選擇了哪個子屬性,以此類推 281 //獲取當前url中已選擇屬性的值,並保留在數組中 282 //!這裏要做循環,是由於避免屬性爲0或者空時,致使出錯,由於直接把$filter_attr 賦值給 $temp_arrt_url_arr會出錯。 283 //RETURN:Array ( [0] => 163 [1] => 216 [2] => 160 [3] => 186 ) 284 $temp_arrt_url_arr = array(); 285 for ($i = 0; $i < count($cat_filter_attr); $i++) { 286 $temp_arrt_url_arr[$i] = !empty($filter_attr[$i]) ? $filter_attr[$i] : 0; 287 } 288 289 //這裏是該屬性下,選擇所有時的數組形式 290 //哪個屬性的值爲0,即說明用戶選擇的是該屬性的所有選項 291 //爲「所有」生成url 292 //DATA:Array ( [0] => 0 [1] => 216 [2] => 160 [3] => 186 ) 293 $temp_arrt_url_arr[$key] = 0; //「所有」的信息生成 294 $temp_arrt_url = implode('.', $temp_arrt_url_arr); 295 $all_attr_list[$key]['attr_list'][0]['attr_value'] = $_LANG['all_attribute']; 296 $all_attr_list[$key]['attr_list'][0]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>$price_min, 'price_max'=>$price_max, 'filter_attr'=>$temp_arrt_url), $cat['cat_name']); 297 $all_attr_list[$key]['attr_list'][0]['selected'] = empty($filter_attr[$key]) ? 1 : 0; 298 299 //循環計算子屬性的相關數組:屬性值,屬性是否選擇,屬性的url 300 //判斷當前子屬性,是否被選中狀態 301 //RETURN:Array ( [0] => Array ( [filter_attr_name] => 顏色 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=0.216.160.186 [selected] => 0 ) [1] => Array ( [attr_value] => 灰色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=167.216.160.186 [selected] => 0 ) [2] => Array ( [attr_value] => 白色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=198.216.160.186 [selected] => 0 ) [3] => Array ( [attr_value] => 金色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=197.216.160.186 [selected] => 0 ) [4] => Array ( [attr_value] => 黑色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) ) ) [1] => Array ( [filter_attr_name] => 屏幕大小 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.0.160.186 [selected] => 0 ) [1] => Array ( [attr_value] => 1.75英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.229.160.186 [selected] => 0 ) [2] => Array ( [attr_value] => 2.0英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [3] => Array ( [attr_value] => 2.2英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.223.160.186 [selected] => 0 ) [4] => Array ( [attr_value] => 2.6英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.156.160.186 [selected] => 0 ) [5] => Array ( [attr_value] => 2.8英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.200.160.186 [selected] => 0 ) ) ) [2] => Array ( [filter_attr_name] => 手機制式 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.0.186 [selected] => 0 ) [1] => Array ( [attr_value] => CDMA [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.202.186 [selected] => 0 ) [2] => Array ( [attr_value] => GSM,850,900,1800,1900 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [3] => Array ( [attr_value] => GSM,900,1800,1900,2100 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.195.186 [selected] => 0 ) ) ) [3] => Array ( [filter_attr_name] => 外觀樣式 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.0 [selected] => 0 ) [1] => Array ( [attr_value] => 滑蓋 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.199 [selected] => 0 ) [2] => Array ( [attr_value] => 直板 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) ) ) ) 302 foreach ($attr_list as $k => $v) { 303 $temp_key = $k + 1; 304 $temp_arrt_url_arr[$key] = $v['goods_id']; //爲url中表明當前篩選屬性的位置變量賦值,並生成以‘.’分隔的篩選屬性字符串 305 $temp_arrt_url = implode('.', $temp_arrt_url_arr); 306 307 $all_attr_list[$key]['attr_list'][$temp_key]['attr_value'] = $v['attr_value']; 308 $all_attr_list[$key]['attr_list'][$temp_key]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>$price_min, 'price_max'=>$price_max, 'filter_attr'=>$temp_arrt_url), $cat['cat_name']); 309 310 if (!empty($filter_attr[$key]) AND $filter_attr[$key] == $v['goods_id']) { //處理已被選擇的子屬性 311 $all_attr_list[$key]['attr_list'][$temp_key]['selected'] = 1; 312 } 313 else { 314 $all_attr_list[$key]['attr_list'][$temp_key]['selected'] = 0; 315 } 316 } 317 } 318 } 319 //爲模板注入變量 320 $smarty->assign('filter_attr_list', $all_attr_list); 321 322 323 /* 擴展商品查詢條件 */ 324 if (!empty($filter_attr)) { 325 $ext_sql = "SELECT DISTINCT(b.goods_id) FROM " . $ecs->table('goods_attr') . " AS a, " . $ecs->table('goods_attr') . " AS b " . "WHERE "; 326 $ext_group_goods = array(); 327 foreach ($filter_attr AS $k => $v) { // 查出符合全部篩選屬性條件的商品id */ 328 if (is_numeric($v) && $v !=0 ) { 329 $sql = $ext_sql . "b.attr_value = a.attr_value AND b.attr_id = " . $cat_filter_attr[$k] ." AND a.goods_attr_id = " . $v; 330 $ext_group_goods = $db->getColCached($sql); 331 $ext .= ' AND ' . db_create_in($ext_group_goods, 'g.goods_id'); 332 } 333 } 334 } 335 } 336 ///<<==================結束---商品屬性處理==================/// 337 338 //向模板,載入一些前臺,必備的變量和常量 339 assign_template('c', array($cat_id)); 340 341 //RETURN:Array ( [title] => 夏新_GSM手機_手機類型_ECSHOP演示站 - Powered by ECShop [ur_here] => 首頁 > 手機類型 > GSM手機 > 夏新 ) 342 $position = assign_ur_here($cat_id, $brand_name); 343 344 $smarty->assign('page_title', $position['title']); // 頁面標題 345 $smarty->assign('ur_here', $position['ur_here']); // 當前位置 346 347 $smarty->assign('categories', get_categories_tree($cat_id)); // 分類樹 348 $smarty->assign('helps', get_shop_help()); // 網店幫助 349 $smarty->assign('top_goods', get_top10()); // 銷售排行 350 $smarty->assign('show_marketprice', $_CFG['show_marketprice']); //是否顯示市場價 351 $smarty->assign('category', $cat_id); 352 $smarty->assign('brand_id', $brand); 353 $smarty->assign('price_max', $price_max); 354 $smarty->assign('price_min', $price_min); 355 $smarty->assign('filter_attr', $filter_attr_str); 356 $smarty->assign('feed_url', ($_CFG['rewrite'] == 1) ? "feed-c$cat_id.xml" : 'feed.php?cat=' . $cat_id); // RSS URL 357 358 if ($brand > 0) { 359 $arr['all'] = array('brand_id' => 0, 360 'brand_name' => $GLOBALS['_LANG']['all_goods'], 361 'brand_logo' => '', 362 'goods_num' => '', 363 'url' => build_uri('category', array('cid'=>$cat_id), $cat['cat_name']) 364 ); 365 } else { 366 $arr = array(); 367 } 368 369 $brand_list = array_merge($arr, get_brands($cat_id, 'category')); 370 $smarty->assign('data_dir', DATA_DIR); //網站data目錄 371 $smarty->assign('brand_list', $brand_list); 372 $smarty->assign('promotion_info', get_promotion_info()); //獲取推薦信息 373 374 /* 調查 */ 375 $vote = get_vote(); 376 if (!empty($vote)) { 377 $smarty->assign('vote_id', $vote['id']); 378 $smarty->assign('vote', $vote['content']); 379 } 380 381 //獲取最熱銷、推薦和最熱賣商品 382 $smarty->assign('best_goods', get_category_recommend_goods('best', $children, $brand, $price_min, $price_max, $ext)); 383 $smarty->assign('promotion_goods', get_category_recommend_goods('promote', $children, $brand, $price_min, $price_max, $ext)); 384 $smarty->assign('hot_goods', get_category_recommend_goods('hot', $children, $brand, $price_min, $price_max, $ext)); 385 //獲取該前狀態下,商品的數量 386 $count = get_cagtegory_goods_count($children, $brand, $price_min, $price_max, $ext); 387 //最大頁數 388 $max_page = ($count> 0) ? ceil($count / $size) : 1; 389 if ($page > $max_page) { 390 $page = $max_page; 391 } 392 393 //獲取該欄目下的全部商品 394 $goodslist = category_get_goods($children, $brand, $price_min, $price_max, $ext, $size, $page, $sort, $order); 395 396 //判斷選擇了列表仍是圖片方式顯示方式 397 if($display == 'grid') { 398 if(count($goodslist) % 2 != 0) { 399 $goodslist[] = array(); 400 } 401 } 402 403 $smarty->assign('goods_list', $goodslist); //注入商品列表 404 $smarty->assign('category', $cat_id); //注入分類id 405 $smarty->assign('script_name', 'category'); //注入該腳本的名稱 406 407 assign_pager('category', $cat_id, $count, $size, $sort, $order, $page, '', $brand, $price_min, $price_max, $display, $filter_attr_str); // 分頁 408 assign_dynamic('category'); // 動態內容 409 } 410 $smarty->display('category.dwt', $cache_id); 411 ?>
2.分步分析其實現過程:
1)第一步,首先,文件一開頭,必定是接收前臺頁面發送過來的各類POST和GET參數了,這裏主要仍是指地址欄GET方式傳過來的參數了。
1 //====> 2.首先獲取全部GET和POST中,可用於搜索的參數的值。 2 //====> 若沒有此參數,則說明,並無用此參數來搜索,默認要給它一個默認值。 3 /* 初始化分頁信息 */ 4 $page = isset($_REQUEST['page']) && intval($_REQUEST['page']) > 0 ? intval($_REQUEST['page']) : 1; 5 $size = isset($_CFG['page_size']) && intval($_CFG['page_size']) > 0 ? intval($_CFG['page_size']) : 10; 6 $brand = isset($_REQUEST['brand']) && intval($_REQUEST['brand']) > 0 ? intval($_REQUEST['brand']) : 0; 7 $price_max = isset($_REQUEST['price_max']) && intval($_REQUEST['price_max']) > 0 ? intval($_REQUEST['price_max']) : 0; 8 $price_min = isset($_REQUEST['price_min']) && intval($_REQUEST['price_min']) > 0 ? intval($_REQUEST['price_min']) : 0; 9 $filter_attr_str = isset($_REQUEST['filter_attr']) ? htmlspecialchars(trim($_REQUEST['filter_attr'])) : '0'; 10 $filter_attr_str = urldecode($filter_attr_str); 11 $filter_attr = empty($filter_attr_str) ? '' : explode('.', trim($filter_attr_str)); 12 13 /* 排序、顯示方式以及類型 */ 14 $default_display_type = $_CFG['show_order_type'] == '0' ? 'list' : ($_CFG['show_order_type'] == '1' ? 'grid' : 'text'); 15 $default_sort_order_method = $_CFG['sort_order_method'] == '0' ? 'DESC' : 'ASC'; 16 $default_sort_order_type = $_CFG['sort_order_type'] == '0' ? 'goods_id' : ($_CFG['sort_order_type'] == '1' ? 'shop_price' : 'last_update'); 17 18 $sort = (isset($_REQUEST['sort']) && in_array(trim(strtolower($_REQUEST['sort'])), array('goods_id', 'shop_price', 'last_update'))) ? trim($_REQUEST['sort']) : $default_sort_order_type; 19 $order = (isset($_REQUEST['order']) && in_array(trim(strtoupper($_REQUEST['order'])), array('ASC', 'DESC'))) ? trim($_REQUEST['order']) : $default_sort_order_method; 20 $display = (isset($_REQUEST['display']) && in_array(trim(strtolower($_REQUEST['display'])), array('list', 'grid', 'text'))) ? trim($_REQUEST['display']) : (isset($_COOKIE['ECS']['display']) ? $_COOKIE['ECS']['display'] : $default_display_type); 21 $display = in_array($display, array('list', 'grid', 'text')) ? $display : 'text'; 22 setcookie('ECS[display]', $display, gmtime() + 86400 * 7);
2)第二步,處理商品分類參數,並獲取該分類的詳細信息:
1 //====> 3.把該欄目下的全部子欄目id獲取,若是沒有子欄目,則是自身。 2 //===> TABLE:ecs_category 3 //====> RETURN:id=3 => g.cat_id IN ('3') 或 id=6 => g.cat_id IN ('6','8','9','11','7') 4 //====> 說明:ecshop的特色是,頂級欄目下也能夠添加商品,因此會把頂級欄目id也放在數組裏面 5 $children = get_children($cat_id); 6 7 //====> 4.得到該分類的相關信息。如:分類名稱、價格分級、篩選屬性、父id 8 //===> TABLE:ecs_category 9 //====> RETURN:Array ( [cat_name] => GSM手機 [keywords] => [cat_desc] => [style] => [grade] => 4 [filter_attr] => 185,189,173,178 [parent_id] => 1 ) 10 $cat = get_cat_info($cat_id);
3)第三步,處理價格,並對商品價格進行區間的劃分:
1 ///>>================開始---商品價格區間處理==================>>/// 2 //===> 6.獲取該分類cat的價格分級: 3 //===> ①若是價格分級=0,那麼獲取直接父類的價格分級。(Ⅰ若是父類價格也=0,那麼就是不用價格分級 ) 4 //===> ②若是價格分級!=0,那麼就是自身的價格分級。 5 //===> TABLE:ecs_category 6 //===> RETURN:$cat['grade']=4 7 /* 獲取價格分級 */ 8 if ($cat['grade'] == 0 && $cat['parent_id'] != 0) { // ==>若是價格分級爲空,可是它還有上級分類,那麼取直接上級的價格分級等數 9 $cat['grade'] = get_parent_grade($cat_id); //若是當前分類級別爲空,取最近的上級分類 10 } 11 12 //===> 7.對價格區間進行劃分。 ecshop的劃分方法,是根據算法來的,比較複雜。 13 //===> 若是價格分級>1,那麼就執行價格區間劃分 14 if ($cat['grade'] > 1) { 15 /* 須要價格分級 */ 16 17 /* 18 算法思路: 19 一、當分級大於1時,進行價格分級 20 二、取出該類下商品價格的最大值、最小值 21 三、根據商品價格的最大值來計算商品價格的分級數量級: 22 價格範圍(不含最大值) 分級數量級 23 0-0.1 0.001 24 0.1-1 0.01 25 1-10 0.1 26 10-100 1 27 100-1000 10 28 1000-10000 100 29 四、計算價格跨度: 30 取整((最大值-最小值) / (價格分級數) / 數量級) * 數量級 31 五、根據價格跨度計算價格範圍區間 32 六、查詢數據庫 33 34 可能存在問題: 35 一、 36 因爲價格跨度是由最大值、最小值計算出來的 37 而後再經過價格跨度來肯定顯示時的價格範圍區間 38 因此可能會存在價格分級數量不正確的問題 39 該問題沒有證實 40 二、 41 當價格=最大值時,分級會多出來,已被證實存在 42 */ 43 44 //===> 得到當前分類下商品價格的最大值、最小值 45 //===> 得到全部擴展分類屬於指定分類的全部商品ID ,其中goods_id = 16的商品的擴展屬於分類3 46 //===> TABLE:ecs_goods 和 ecs_goods_cat 47 //===> SQL:SELECT min(g.shop_price) AS min, max(g.shop_price) as max FROM `ecshop`.`ecs_goods` AS g WHERE (g.cat_id IN ('5') OR g.goods_id IN ('8','16') ) AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 48 //===> RETURN:Array ( [min] => 280.00 [max] => 5999.00 ) 49 $sql = "SELECT min(g.shop_price) AS min, max(g.shop_price) as max ". 50 " FROM " . $ecs->table('goods'). " AS g ". 51 " WHERE ($children OR " . get_extension_goods($children) . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '; 52 $row = $db->getRow($sql); 53 54 55 //===> 按照公式計算出最低價格和最高價格、以及價格跨度 56 //===============↓↓↓先不作討論=============== 57 // 取得價格分級最小單位級數,好比,千元商品最小以100爲級數 58 $price_grade = 0.0001; 59 for($i=-2; $i<= log10($row['max']); $i++) { 60 $price_grade *= 10; 61 } 62 63 //價格跨度 64 $dx = ceil(($row['max'] - $row['min']) / ($cat['grade']) / $price_grade) * $price_grade; 65 if($dx == 0) { 66 $dx = $price_grade; 67 } 68 69 for($i = 1; $row['min'] > $dx * $i; $i ++); 70 71 for($j = 1; $row['min'] > $dx * ($i-1) + $price_grade * $j; $j++); 72 $row['min'] = $dx * ($i-1) + $price_grade * ($j - 1); 73 74 for(; $row['max'] >= $dx * $i; $i ++); 75 $row['max'] = $dx * ($i) + $price_grade * ($j - 1); 76 77 //===>這裏打印最高價格和最低價格:$row=>Array ( [min] => 200 [max] => 6200 ) 78 //===>這裏打印價格跨度:$dx = 1500 79 80 //===============先不作討論↑↑↑==================// 81 82 83 //===> 根據商品的價格、價格區間的最低價格、以及價格跨度,計算該商品價格屬於哪個區間內。 84 //===> 獲取屬於該價格區間內的商品的數量、獲取sn則屬於哪個區間sn=0爲200-1700、sn=1爲1700-3200、sn=3爲4700-6200。 85 //===> 由於沒有商品價格屬於第二區間,則不存在sn=2,那麼3200-4700則沒有任何商品 86 //===> TABLE:ecs_goods 和 ecs_goods_cat 87 //===> SQL:SELECT (FLOOR((g.shop_price - 200) / 1500)) AS sn, COUNT(*) AS goods_num FROM `ecshop`.`ecs_goods` AS g WHERE (g.cat_id IN ('3') OR g.goods_id IN ('16') ) AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 GROUP BY sn 88 //===>RETURN:Array ( [0] => Array ( [sn] => 0 [goods_num] => 6 ) [1] => Array ( [sn] => 1 [goods_num] => 5 ) [2] => Array ( [sn] => 3 [goods_num] => 1 ) ) 89 $sql = "SELECT (FLOOR((g.shop_price - $row[min]) / $dx)) AS sn, COUNT(*) AS goods_num ". 90 " FROM " . $ecs->table('goods') . " AS g ". 91 " WHERE ($children OR " . get_extension_goods($children) . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. 92 " GROUP BY sn "; 93 $price_grade = $db->getAll($sql); 94 95 96 //===> 根據價格等級price_grade,計算真正的價格區間。 97 //===> 方法build_uri()重要:要爲每個價格區間,生成一個url超連接,以備前臺點擊搜索用 98 //===> 並根據價格參數,判斷該區間,是不是當前被搜索的區間 99 //===> 把價格區間,注入模板,供前臺使用 100 //===> RETURN:Array ( [0] => Array ( [sn] => 0 [goods_num] => 6 [start] => 0 [end] => 0 [price_range] => 所有 [url] => category.php?id=3&brand=1&price_min=0&price_max=0&filter_attr=163.216.160.186 [selected] => 0 ) [1] => Array ( [sn] => 1 [goods_num] => 6 [start] => 200 [end] => 1700 [price_range] => 200 - 1700 [formated_start] => ¥200元 [formated_end] => ¥1700元 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [2] => Array ( [sn] => 3 [goods_num] => 5 [start] => 1700 [end] => 3200 [price_range] => 1700 - 3200 [formated_start] => ¥1700元 [formated_end] => ¥3200元 [url] => category.php?id=3&brand=1&price_min=1700&price_max=3200&filter_attr=163.216.160.186 [selected] => 0 ) [3] => Array ( [goods_num] => 1 [start] => 4700 [end] => 6200 [price_range] => 4700 - 6200 [formated_start] => ¥4700元 [formated_end] => ¥6200元 [url] => category.php?id=3&brand=1&price_min=4700&price_max=6200&filter_attr=163.216.160.186 [selected] => 0 ) ) 101 foreach ($price_grade as $key=>$val) { 102 $temp_key = $key + 1; 103 $price_grade[$temp_key]['goods_num'] = $val['goods_num']; 104 $price_grade[$temp_key]['start'] = $row['min'] + round($dx * $val['sn']); 105 $price_grade[$temp_key]['end'] = $row['min'] + round($dx * ($val['sn'] + 1)); 106 $price_grade[$temp_key]['price_range'] = $price_grade[$temp_key]['start'] . ' - ' . $price_grade[$temp_key]['end']; 107 $price_grade[$temp_key]['formated_start'] = price_format($price_grade[$temp_key]['start']); 108 $price_grade[$temp_key]['formated_end'] = price_format($price_grade[$temp_key]['end']); 109 $price_grade[$temp_key]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>$price_grade[$temp_key]['start'], 'price_max'=> $price_grade[$temp_key]['end'], 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 110 /* 判斷價格區間是否被選中 */ 111 if (isset($_REQUEST['price_min']) && $price_grade[$temp_key]['start'] == $price_min && $price_grade[$temp_key]['end'] == $price_max) { 112 $price_grade[$temp_key]['selected'] = 1; 113 } 114 else { 115 $price_grade[$temp_key]['selected'] = 0; 116 } 117 } 118 //補充一個選擇所有的類型的數組 119 $price_grade[0]['start'] = 0; 120 $price_grade[0]['end'] = 0; 121 $price_grade[0]['price_range'] = $_LANG['all_attribute']; 122 $price_grade[0]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>0, 'price_max'=> 0, 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 123 $price_grade[0]['selected'] = empty($price_max) ? 1 : 0; 124 //把價格區間數組,注入模板文件 125 $smarty->assign('price_grade', $price_grade); 126 } 127 ///<<================結束---商品價格區間處理==================<</// 128
4)第四步,處理品牌,併爲每個品牌生成url。
1 ///>>================開始---商品品牌處理==================>>/// 2 //====> ???db_create_in(array_unique(array_merge(array($cat_id), array_keys(cat_list($cat_id, 0, false))))) . ") 3 //===> 品牌篩選功能:把該欄目下(其中包括擴展分類下的商品),全部商品的品牌獲取,但不能重複。 4 //===> 品牌下有商品而且商品狀態正常,才能把該品牌取出。沒有商品的品牌不能取出 5 //===> TABLE:ecs_brand、ecs_goods 和 ecs_goods_cat 6 //===> SQL:SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num FROM `ecshop`.`ecs_brand`AS b, `ecshop`.`ecs_goods` AS g LEFT JOIN `ecshop`.`ecs_goods_cat` AS gc ON g.goods_id = gc.goods_id WHERE g.brand_id = b.brand_id AND (g.cat_id IN ('3') OR gc.cat_id IN ('3') ) AND b.is_show = 1 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 GROUP BY b.brand_id HAVING goods_num > 0 ORDER BY b.sort_order, b.brand_id ASC 7 //===> RETURN:Array ( [0] => Array ( [brand_id] => 1 [brand_name] => 諾基亞 [goods_num] => 3 ) [1] => Array ( [brand_id] => 2 [brand_name] => 摩托羅拉 [goods_num] => 1 ) [2] => Array ( [brand_id] => 3 [brand_name] => 多普達 [goods_num] => 1 ) [3] => Array ( [brand_id] => 4 [brand_name] => 飛利浦 [goods_num] => 2 ) [4] => Array ( [brand_id] => 5 [brand_name] => 夏新 [goods_num] => 1 ) [5] => Array ( [brand_id] => 6 [brand_name] => 三星 [goods_num] => 2 ) [6] => Array ( [brand_id] => 7 [brand_name] => 索愛 [goods_num] => 1 ) [7] => Array ( [brand_id] => 9 [brand_name] => 聯想 [goods_num] => 1 ) [8] => Array ( [brand_id] => 10 [brand_name] => 金立 [goods_num] => 1 ) ) 8 /* 品牌篩選 */ 9 $sql = "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ". 10 "FROM " . $GLOBALS['ecs']->table('brand') . "AS b, ". 11 $GLOBALS['ecs']->table('goods') . " AS g LEFT JOIN ". $GLOBALS['ecs']->table('goods_cat') . " AS gc ON g.goods_id = gc.goods_id " . 12 "WHERE g.brand_id = b.brand_id AND ($children OR " . 'gc.cat_id ' . db_create_in(array_unique(array_merge(array($cat_id), array_keys(cat_list($cat_id, 0, false))))) . ") AND b.is_show = 1 " . 13 " AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 ". 14 "GROUP BY b.brand_id HAVING goods_num > 0 ORDER BY b.sort_order, b.brand_id ASC"; 15 $brands = $GLOBALS['db']->getAll($sql); 16 17 //===> 把該分類下全部商品的品牌,組合成數組,給前臺調用 18 //===> 方法build_uri()重要:要爲每品牌,生成一個url超連接,以備前臺點擊搜索用 19 //===> 把數組注入模板文件 20 //====! 這樣一種組織數組的方式,有它的缺陷:就是說不可以把每個品牌下面的,商品的數量保存下來,同時也會有一些無用的數據,摻雜其中。 21 //RETURN:Array ( [0] => Array ( [brand_id] => 1 [brand_name] => 所有 [goods_num] => 3 [url] => category.php?id=3&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [1] => Array ( [brand_id] => 2 [brand_name] => 諾基亞 [goods_num] => 1 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [2] => Array ( [brand_id] => 3 [brand_name] => 摩托羅拉 [goods_num] => 1 [url] => category.php?id=3&brand=2&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [3] => Array ( [brand_id] => 4 [brand_name] => 多普達 [goods_num] => 2 [url] => category.php?id=3&brand=3&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [4] => Array ( [brand_id] => 5 [brand_name] => 飛利浦 [goods_num] => 1 [url] => category.php?id=3&brand=4&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [5] => Array ( [brand_id] => 6 [brand_name] => 夏新 [goods_num] => 2 [url] => category.php?id=3&brand=5&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [6] => Array ( [brand_id] => 7 [brand_name] => 三星 [goods_num] => 1 [url] => category.php?id=3&brand=6&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [7] => Array ( [brand_id] => 9 [brand_name] => 索愛 [goods_num] => 1 [url] => category.php?id=3&brand=7&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [8] => Array ( [brand_id] => 10 [brand_name] => 聯想 [goods_num] => 1 [url] => category.php?id=3&brand=9&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) [9] => Array ( [brand_name] => 金立 [url] => category.php?id=3&brand=10&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 0 ) ) 22 foreach ($brands AS $key => $val) { 23 $temp_key = $key + 1; 24 $brands[$temp_key]['brand_name'] = $val['brand_name']; 25 $brands[$temp_key]['url'] = build_uri('category', array('cid' => $cat_id, 'bid' => $val['brand_id'], 'price_min'=>$price_min, 'price_max'=> $price_max, 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 26 /* 判斷品牌是否被選中 */ 27 if ($brand == $brands[$key]['brand_id']) { 28 $brands[$temp_key]['selected'] = 1; 29 } else { 30 $brands[$temp_key]['selected'] = 0; 31 } 32 } 33 //補充一個選擇所有品牌的數組 34 $brands[0]['brand_name'] = $_LANG['all_attribute']; 35 $brands[0]['url'] = build_uri('category', array('cid' => $cat_id, 'bid' => 0, 'price_min'=>$price_min, 'price_max'=> $price_max, 'filter_attr'=>$filter_attr_str), $cat['cat_name']); 36 $brands[0]['selected'] = empty($brand) ? 1 : 0; 37 //把品牌數組注入模板 38 $smarty->assign('brands', $brands); 39 ///<<==================結束---商品品牌處理==================<<///
5)第五步,處理商品的屬性,併爲每個屬性生成url。
1 ///>>==================開始---商品屬性處理==================>>/// 2 /* 屬性篩選 */ 3 $ext = ''; //商品查詢條件擴展 4 if ($cat['filter_attr'] > 0) { 5 //===>須要篩選的屬性,是人工在後臺添加的,存放在ecs_category 表的中 filter_attr字段裏面,格式如:185,189,120,190 6 //===>RETURN:Array ( [0] => 185 [1] => 189 [2] => 173 [3] => 178 ) 7 $cat_filter_attr = explode(',', $cat['filter_attr']); //提取出此分類的篩選屬性 8 9 //===> 而後,對每個屬性(此屬性是主屬性,下面還有子屬性),循環進行操做 10 //===> ①獲取該屬性的屬性名 11 //===> ②獲取該屬性的全部子屬性(子屬性必須是有被商品在使用的,否則,不要將其顯示出來) 12 //===> 意義:由於該屬性涉及到搜索參數,若是該屬性下自己沒有商品,那麼就沒有顯示出來的意義了。 13 //===> RETURN: Array ( [0] => Array ( [attr_id] => 185 [goods_id] => 167 [attr_value] => 灰色 ) [1] => Array ( [attr_id] => 185 [goods_id] => 198 [attr_value] => 白色 ) [2] => Array ( [attr_id] => 185 [goods_id] => 197 [attr_value] => 金色 ) [3] => Array ( [attr_id] => 185 [goods_id] => 163 [attr_value] => 黑色 ) ) 14 $all_attr_list = array(); 15 foreach ($cat_filter_attr AS $key => $value) { 16 $sql = "SELECT a.attr_name FROM " . $ecs->table('attribute') . " AS a, " . $ecs->table('goods_attr') . " AS ga, " . $ecs->table('goods') . " AS g WHERE ($children OR " . get_extension_goods($children) . ") AND a.attr_id = ga.attr_id AND g.goods_id = ga.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND a.attr_id='$value'"; 17 if($temp_name = $db->getOne($sql)) { 18 //獲取該屬性名(主屬性) 19 $all_attr_list[$key]['filter_attr_name'] = $temp_name; 20 21 //獲取該屬性的全部子屬性(子屬性必須是有被商品在使用的,否則,不要將其顯示出來) 22 //RETURN: Array ( [0] => Array ( [attr_id] => 185 [goods_id] => 167 [attr_value] => 灰色 ) [1] => Array ( [attr_id] => 185 [goods_id] => 198 [attr_value] => 白色 ) [2] => Array ( [attr_id] => 185 [goods_id] => 197 [attr_value] => 金色 ) [3] => Array ( [attr_id] => 185 [goods_id] => 163 [attr_value] => 黑色 ) ) 23 $sql = "SELECT a.attr_id, MIN(a.goods_attr_id ) AS goods_id, a.attr_value AS attr_value FROM " . $ecs->table('goods_attr') . " AS a, " . $ecs->table('goods') . 24 " AS g" . 25 " WHERE ($children OR " . get_extension_goods($children) . ') AND g.goods_id = a.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. 26 " AND a.attr_id='$value' ". 27 " GROUP BY a.attr_value"; 28 $attr_list = $db->getAll($sql); 29 30 //若是後臺指定該分類下,用於搜索的屬性的組數,是跟地址欄中filter_attr=0.0.0.0 中0的個數是同樣的,並且順序都是同樣的 31 //第一個0,表示第一組屬性中,它選擇了哪個子屬性,以此類推 32 //獲取當前url中已選擇屬性的值,並保留在數組中 33 //!這裏要做循環,是由於避免屬性爲0或者空時,致使出錯,由於直接把$filter_attr 賦值給 $temp_arrt_url_arr會出錯。 34 //RETURN:Array ( [0] => 163 [1] => 216 [2] => 160 [3] => 186 ) 35 $temp_arrt_url_arr = array(); 36 for ($i = 0; $i < count($cat_filter_attr); $i++) { 37 $temp_arrt_url_arr[$i] = !empty($filter_attr[$i]) ? $filter_attr[$i] : 0; 38 } 39 40 //這裏是該屬性下,選擇所有時的數組形式 41 //哪個屬性的值爲0,即說明用戶選擇的是該屬性的所有選項 42 //爲「所有」生成url 43 //DATA:Array ( [0] => 0 [1] => 216 [2] => 160 [3] => 186 ) 44 $temp_arrt_url_arr[$key] = 0; //「所有」的信息生成 45 $temp_arrt_url = implode('.', $temp_arrt_url_arr); 46 $all_attr_list[$key]['attr_list'][0]['attr_value'] = $_LANG['all_attribute']; 47 $all_attr_list[$key]['attr_list'][0]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>$price_min, 'price_max'=>$price_max, 'filter_attr'=>$temp_arrt_url), $cat['cat_name']); 48 $all_attr_list[$key]['attr_list'][0]['selected'] = empty($filter_attr[$key]) ? 1 : 0; 49 50 //循環計算子屬性的相關數組:屬性值,屬性是否選擇,屬性的url 51 //判斷當前子屬性,是否被選中狀態 52 //RETURN:Array ( [0] => Array ( [filter_attr_name] => 顏色 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=0.216.160.186 [selected] => 0 ) [1] => Array ( [attr_value] => 灰色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=167.216.160.186 [selected] => 0 ) [2] => Array ( [attr_value] => 白色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=198.216.160.186 [selected] => 0 ) [3] => Array ( [attr_value] => 金色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=197.216.160.186 [selected] => 0 ) [4] => Array ( [attr_value] => 黑色 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) ) ) [1] => Array ( [filter_attr_name] => 屏幕大小 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.0.160.186 [selected] => 0 ) [1] => Array ( [attr_value] => 1.75英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.229.160.186 [selected] => 0 ) [2] => Array ( [attr_value] => 2.0英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [3] => Array ( [attr_value] => 2.2英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.223.160.186 [selected] => 0 ) [4] => Array ( [attr_value] => 2.6英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.156.160.186 [selected] => 0 ) [5] => Array ( [attr_value] => 2.8英寸 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.200.160.186 [selected] => 0 ) ) ) [2] => Array ( [filter_attr_name] => 手機制式 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.0.186 [selected] => 0 ) [1] => Array ( [attr_value] => CDMA [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.202.186 [selected] => 0 ) [2] => Array ( [attr_value] => GSM,850,900,1800,1900 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) [3] => Array ( [attr_value] => GSM,900,1800,1900,2100 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.195.186 [selected] => 0 ) ) ) [3] => Array ( [filter_attr_name] => 外觀樣式 [attr_list] => Array ( [0] => Array ( [attr_value] => 所有 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.0 [selected] => 0 ) [1] => Array ( [attr_value] => 滑蓋 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.199 [selected] => 0 ) [2] => Array ( [attr_value] => 直板 [url] => category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186 [selected] => 1 ) ) ) ) 53 foreach ($attr_list as $k => $v) { 54 $temp_key = $k + 1; 55 $temp_arrt_url_arr[$key] = $v['goods_id']; //爲url中表明當前篩選屬性的位置變量賦值,並生成以‘.’分隔的篩選屬性字符串 56 $temp_arrt_url = implode('.', $temp_arrt_url_arr); 57 58 $all_attr_list[$key]['attr_list'][$temp_key]['attr_value'] = $v['attr_value']; 59 $all_attr_list[$key]['attr_list'][$temp_key]['url'] = build_uri('category', array('cid'=>$cat_id, 'bid'=>$brand, 'price_min'=>$price_min, 'price_max'=>$price_max, 'filter_attr'=>$temp_arrt_url), $cat['cat_name']); 60 61 if (!empty($filter_attr[$key]) AND $filter_attr[$key] == $v['goods_id']) { //處理已被選擇的子屬性 62 $all_attr_list[$key]['attr_list'][$temp_key]['selected'] = 1; 63 } 64 else { 65 $all_attr_list[$key]['attr_list'][$temp_key]['selected'] = 0; 66 } 67 } 68 } 69 } 70 //爲模板注入變量 71 $smarty->assign('filter_attr_list', $all_attr_list); 72 73 74 /* 擴展商品查詢條件 */ 75 if (!empty($filter_attr)) { 76 $ext_sql = "SELECT DISTINCT(b.goods_id) FROM " . $ecs->table('goods_attr') . " AS a, " . $ecs->table('goods_attr') . " AS b " . "WHERE "; 77 $ext_group_goods = array(); 78 foreach ($filter_attr AS $k => $v) { // 查出符合全部篩選屬性條件的商品id */ 79 if (is_numeric($v) && $v !=0 ) { 80 $sql = $ext_sql . "b.attr_value = a.attr_value AND b.attr_id = " . $cat_filter_attr[$k] ." AND a.goods_attr_id = " . $v; 81 $ext_group_goods = $db->getColCached($sql); 82 $ext .= ' AND ' . db_create_in($ext_group_goods, 'g.goods_id'); 83 } 84 } 85 } 86 } 87 ///<<==================結束---商品屬性處理==================///
6)第六步,根據以上計算的條件,查詢商品列表,並計算商品的數量等等,把變量注入模板中去。
1 //向模板,載入一些前臺,必備的變量和常量 2 assign_template('c', array($cat_id)); 3 4 //RETURN:Array ( [title] => 夏新_GSM手機_手機類型_ECSHOP演示站 - Powered by ECShop [ur_here] => 首頁 > 手機類型 > GSM手機 > 夏新 ) 5 $position = assign_ur_here($cat_id, $brand_name); 6 7 $smarty->assign('page_title', $position['title']); // 頁面標題 8 $smarty->assign('ur_here', $position['ur_here']); // 當前位置 9 10 $smarty->assign('categories', get_categories_tree($cat_id)); // 分類樹 11 $smarty->assign('helps', get_shop_help()); // 網店幫助 12 $smarty->assign('top_goods', get_top10()); // 銷售排行 13 $smarty->assign('show_marketprice', $_CFG['show_marketprice']); //是否顯示市場價 14 $smarty->assign('category', $cat_id); 15 $smarty->assign('brand_id', $brand); 16 $smarty->assign('price_max', $price_max); 17 $smarty->assign('price_min', $price_min); 18 $smarty->assign('filter_attr', $filter_attr_str); 19 $smarty->assign('feed_url', ($_CFG['rewrite'] == 1) ? "feed-c$cat_id.xml" : 'feed.php?cat=' . $cat_id); // RSS URL 20 21 if ($brand > 0) { 22 $arr['all'] = array('brand_id' => 0, 23 'brand_name' => $GLOBALS['_LANG']['all_goods'], 24 'brand_logo' => '', 25 'goods_num' => '', 26 'url' => build_uri('category', array('cid'=>$cat_id), $cat['cat_name']) 27 ); 28 } else { 29 $arr = array(); 30 } 31 32 $brand_list = array_merge($arr, get_brands($cat_id, 'category')); 33 $smarty->assign('data_dir', DATA_DIR); //網站data目錄 34 $smarty->assign('brand_list', $brand_list); 35 $smarty->assign('promotion_info', get_promotion_info()); //獲取推薦信息 36 37 /* 調查 */ 38 $vote = get_vote(); 39 if (!empty($vote)) { 40 $smarty->assign('vote_id', $vote['id']); 41 $smarty->assign('vote', $vote['content']); 42 } 43 44 //獲取最熱銷、推薦和最熱賣商品 45 $smarty->assign('best_goods', get_category_recommend_goods('best', $children, $brand, $price_min, $price_max, $ext)); 46 $smarty->assign('promotion_goods', get_category_recommend_goods('promote', $children, $brand, $price_min, $price_max, $ext)); 47 $smarty->assign('hot_goods', get_category_recommend_goods('hot', $children, $brand, $price_min, $price_max, $ext)); 48 //獲取該前狀態下,商品的數量 49 $count = get_cagtegory_goods_count($children, $brand, $price_min, $price_max, $ext); 50 //最大頁數 51 $max_page = ($count> 0) ? ceil($count / $size) : 1; 52 if ($page > $max_page) { 53 $page = $max_page; 54 } 55 56 //獲取該欄目下的全部商品 57 $goodslist = category_get_goods($children, $brand, $price_min, $price_max, $ext, $size, $page, $sort, $order); 58 59 //判斷選擇了列表仍是圖片方式顯示方式 60 if($display == 'grid') { 61 if(count($goodslist) % 2 != 0) { 62 $goodslist[] = array(); 63 } 64 } 65 66 $smarty->assign('goods_list', $goodslist); //注入商品列表 67 $smarty->assign('category', $cat_id); //注入分類id 68 $smarty->assign('script_name', 'category'); //注入該腳本的名稱 69 70 assign_pager('category', $cat_id, $count, $size, $sort, $order, $page, '', $brand, $price_min, $price_max, $display, $filter_attr_str); // 分頁 71 assign_dynamic('category'); // 動態內容 72 } 73 $smarty->display('category.dwt', $cache_id);
說明:以上的代碼中,都有對其實現方法,有很是具體的說明,詳情請見代碼的備註。
總結:分析都最後,其實我有些些失望了,由於這個所謂多條件搜索功能的實現,並不算是很複雜,很高深的東西,都比較簡單(和個人想法差很少)。
不過,我也學到了一些東西,具體以下:
① 對Ecshop商品主要數據表的設計有了瞭解。(下一篇會簡單介紹)
② 原來這裏的要對商品的那些屬性進行篩選,並非程序自動處理,而是管理員後臺指定的。
③ 價格區間的計算,是按照必定的算法計算出來的,比較智能,但數字不太好看(另一種策略,是本身後臺爲每個商品分類,都指定一個價格區間,也是能夠的。)
④ 品牌、價格區間和屬性,都是按照必定的原則從數據庫抽取出來的。即,這些說有的分類或者屬性下,必須是有商品的,纔會把它獲取出來。好比,若是顏色爲黑色的屬性下面是沒有任何商品的,那麼黑色這個屬性,就不該該顯示出來。其餘依次類推。
⑤ 對於一些較爲複雜的mysql語句查詢,有了一些瞭解(但願不斷提升啦。。)
以上,是小弟作的一些小小的分析和總結,我經驗還不豐富啊,有哪一些不對的地方和不足,但願你們指正,我會虛心學習和接受,謝謝啦!!