【PHP開源產品】Ecshop的商品篩選功能實現分析之一

1、首先,說明一下爲何要對category.php文件進行分析。

緣由以下:php

①我的對商城類商品篩選功能的實現比較好奇;html

②對商城中關於商品的數據表設計比較感興趣。(該功能涉及到與數據庫的交互,並且與數據庫中數據表的設計好壞有必定的聯繫);mysql

③多條件(屬性)篩選功能在現今的不少網站都須要用到,很普遍(如:通常商城網、團購網、房產網、信息分類網站等等)。算法

 

但願達到的目的是:sql

①可以對多條件篩選功能有一個初步的認識。(起碼本身作,也可以快速實現吧);數據庫

②對多條件篩選的實現中,數據庫該如何去設計纔會更優化和更合理些(參考前人的經驗);數組

③對多條件篩選中的一些策略或者是技巧,能有一個瞭解(會總結幾點)緩存

 

2、而後,咱們首先看一下如今需求是如何的?(多條件篩選,請參考京東、蘇寧、國美等)

①京東商城的商品篩選功能(截圖):服務器

 

②蘇寧商城的商品篩選功能(截圖)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

結果頁面爲:

 

若是我選擇了多條件搜索,看截圖:

訪問地址爲: http://demo.ecshop.com/category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.0.160.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'] . '&nbsp;-&nbsp;' . $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 ?>
查看category.php所有代碼

 

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);   
View Code

 

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'] . '&nbsp;-&nbsp;' . $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     
View Code

 

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     ///<<==================結束---商品品牌處理==================<<///
View Code

 

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     ///<<==================結束---商品屬性處理==================///
View Code

 

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);
View Code

 

說明:以上的代碼中,都有對其實現方法,有很是具體的說明,詳情請見代碼的備註。

 

 

總結:分析都最後,其實我有些些失望了,由於這個所謂多條件搜索功能的實現,並不算是很複雜,很高深的東西,都比較簡單(和個人想法差很少)。

不過,我也學到了一些東西,具體以下:

① 對Ecshop商品主要數據表的設計有了瞭解。(下一篇會簡單介紹)

② 原來這裏的要對商品的那些屬性進行篩選,並非程序自動處理,而是管理員後臺指定的。

③ 價格區間的計算,是按照必定的算法計算出來的,比較智能,但數字不太好看(另一種策略,是本身後臺爲每個商品分類,都指定一個價格區間,也是能夠的。)

④ 品牌、價格區間和屬性,都是按照必定的原則從數據庫抽取出來的。即,這些說有的分類或者屬性下,必須是有商品的,纔會把它獲取出來。好比,若是顏色爲黑色的屬性下面是沒有任何商品的,那麼黑色這個屬性,就不該該顯示出來。其餘依次類推。

⑤ 對於一些較爲複雜的mysql語句查詢,有了一些瞭解(但願不斷提升啦。。)

 

以上,是小弟作的一些小小的分析和總結,我經驗還不豐富啊,有哪一些不對的地方和不足,但願你們指正,我會虛心學習和接受,謝謝啦!!

相關文章
相關標籤/搜索