PHP头条
热点:

【PHP开源产品】Ecshop的商品筛选功能实现分析之一(主要对category.php进行分析)


一、首先,说明一下为什么要对category.php文件进行分析。

(1)原因如下:

①个人对商城类商品筛选功能的实现比较好奇;

②对商城中关于商品的数据表设计比较感兴趣。(该功能涉及到与数据库的交互,而且与数据库中数据表的设计好坏有一定的联系);

③多条件(属性)筛选功能在现今的很多网站都需要用到,很广泛(如:一般商城网、团购网、房产网、信息分类网站等等)。

(2)希望达到的目的是:

①能够对多条件筛选功能有一个初步的认识。(起码自己做,也能够快速实现吧);

②对多条件筛选的实现中,数据库该如何去设计才会更优化和更合理些(参考前人的经验);

③对多条件筛选中的一些策略或者是技巧,能有一个了解(会总结几点)

 

二、然后,我们首先看一下现在需求是如何的?(多条件筛选,请参考京东、苏宁、国美等)

①京东商城的商品筛选功能(截图):

 

②苏宁商城的商品筛选功能(截图)

 

③国美在线的商品筛选功能(截图)

 

补充:其实,要对该功能的观察,还必须对地址栏,也作一番思考的,我这里就省略了,毕竟如果这样分析,会更简单一些。上面这些例子,只作一个引子吧。后续我会完善它的。

 

④ECSHOP的商品筛选功能实现,展示细节(截图+文字)如下:

1)首先,我本地服务器,给本机安装的ecshop演示网站,配了一个虚拟主机地址:为

“GSM手机”分类下的商品。如下:

 

 

 

如果我想查看品牌为“诺基亚”的手机,那么点击“诺基亚”标签即可:

访问地址为:  

结果页面为:

 

访问地址为: 

结果页面为:

 

 

分析:从上面的地址栏的变化和截图的变化,可以初步看出ecshop的多条件搜索方法是怎么样的了。

猜想1:随着用户每一次点击条件(属性)进行商品筛选时,搜索地址栏会变化,为什么地址栏会变化,归根结底,一定是每一个商品的属性的a标签的超链接地址被改变了。而且是每点击一次,都会随着搜索条件的不同,而改变。

从而我们知道,这个属性的超链接,是动态生成的。ecshop后台一定是作了大量的判断过程,并最终为每一个商品属性,生成一个超链接地址,以防止上一次的搜索条件丢失。

猜想2:商品的价格区间,是根据什么来计算的呢?还是人工后台设置的,京东的商品价格区间,好像都是很有规律的,和ecshop的价格区间,有比较大的区别。别管这么多了,我们还是先研究ecshop的再说。

猜想3:参数 filter_attr=163.0.160.0 中的几个数字,一定代表着下面:颜色、屏幕大小 、手机制式、外观样式属性下,都选择了哪一些值了。

 

----> 带着这样一些疑问,那我们直接去研究一下ecshop是如何实现上面的多条件搜索功能啦。。。GO。。。

首先,我们到ecshop的网站更目录,找到category.php文件,打开它进行研究一下。

 

<? ('IN_ECS', (() . '/includes/init.php' ((DEBUG_MODE & 2) != 2 ->caching = ((['id' = (['id' ((['category' = (['category' } ecs_header("Location: ./\n" = (['page']) && (['page']) > 0 ? (['page']) : 1 = (['page_size']) && (['page_size']) > 0 ? (['page_size']) : 10 = (['brand']) && (['brand']) > 0 ? (['brand']) : 0 = (['price_max']) && (['price_max']) > 0 ? (['price_max']) : 0 = (['price_min']) && (['price_min']) > 0 ? (['price_min']) : 0 = (['filter_attr']) ? ((['filter_attr'])) : '0' = ( = () ? '' : ('.', ( = ['show_order_type'] == '0' ? 'list' : (['show_order_type'] == '1' ? 'grid' : 'text' = ['sort_order_method'] == '0' ? 'DESC' : 'ASC' = ['sort_order_type'] == '0' ? 'goods_id' : (['sort_order_type'] == '1' ? 'shop_price' : 'last_update' = ((['sort']) && (((['sort'])), ('goods_id', 'shop_price', 'last_update'))) ? (['sort']) : = ((['order']) && (((['order'])), ('ASC', 'DESC'))) ? (['order']) : = ((['display']) && (((['display'])), ('list', 'grid', 'text'))) ? (['display']) : ((['ECS']['display']) ? ['ECS']['display'] : = (, ('list', 'grid', 'text')) ? : 'text' ('ECS[display]', , gmtime() + 86400 * 7 = ('%X', ( . '-' . . '-' . .'-' . .'-' . . '-' . . '-' . ['user_rank'] . '-' . ['lang'] .'-'. . '-' . . '-' . . '-' . (!->is_cached('category.dwt', = get_children( = get_cat_info( ( > 0 = "SELECT brand_name FROM " .['ecs']->table('brand'). " WHERE brand_id = ''" = ->getOne( } = '' (['grade'] == 0 && ['parent_id'] != 0) { ['grade'] = get_parent_grade(); (['grade'] > 1 = "SELECT min(g.shop_price) AS min, max(g.shop_price) as max ". " FROM " . ->table('goods'). " AS g ". " WHERE ( OR " . get_extension_goods() . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 ' = ->getRow( = 0.0001 (=-2; <= (['max']); ++ *= 10 = ((['max'] - ['min']) / (['grade']) / ) * ( == 0 = ( = 1; ['min'] > * ; ++ ( = 1; ['min'] > * (-1) + * ; ++ ['min'] = * (-1) + * ( - 1 (; ['max'] >= * ; ++ ['max'] = * () + * ( - 1 = "SELECT (FLOOR((g.shop_price - [min]) / )) AS sn, COUNT(*) AS goods_num ". " FROM " . ->table('goods') . " AS g ". " WHERE ( OR " . get_extension_goods() . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. " GROUP BY sn " = ->getAll( ( => = + 1 []['goods_num'] = ['goods_num' []['start'] = ['min'] + ( * ['sn' []['end'] = ['min'] + ( * (['sn'] + 1 []['price_range'] = []['start'] . '&nbsp;-&nbsp;' . []['end' []['formated_start'] = price_format([]['start' []['formated_end'] = price_format([]['end' []['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>[]['start'], 'price_max'=> []['end'], 'filter_attr'=>), ['cat_name' ((['price_min']) && []['start'] == && []['end'] == []['selected'] = 1 []['selected'] = 0 [0]['start'] = 0 [0]['end'] = 0 [0]['price_range'] = ['all_attribute' [0]['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>0, 'price_max'=> 0, 'filter_attr'=>), ['cat_name' [0]['selected'] = () ? 1 : 0 ->assign('price_grade', = "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ". "FROM " . ['ecs']->table('brand') . "AS b, ". ['ecs']->table('goods') . " AS g LEFT JOIN ". ['ecs']->table('goods_cat') . " AS gc ON g.goods_id = gc.goods_id " . "WHERE g.brand_id = b.brand_id AND ( OR " . 'gc.cat_id ' . db_create_in((((), (cat_list(, 0, ))))) . ") 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" = ['db']->getAll( ( => = + 1 []['brand_name'] = ['brand_name' []['url'] = build_uri('category', ('cid' => , 'bid' => ['brand_id'], 'price_min'=>, 'price_max'=> , 'filter_attr'=>), ['cat_name' ( == []['brand_id' []['selected'] = 1 } []['selected'] = 0 [0]['brand_name'] = ['all_attribute' [0]['url'] = build_uri('category', ('cid' => , 'bid' => 0, 'price_min'=>, 'price_max'=> , 'filter_attr'=>), ['cat_name' [0]['selected'] = () ? 1 : 0 ->assign('brands', = ''; (['filter_attr'] > 0 = (',', ['filter_attr']); = ( => = "SELECT a.attr_name FROM " . ->table('attribute') . " AS a, " . ->table('goods_attr') . " AS ga, " . ->table('goods') . " AS g WHERE ( OR " . get_extension_goods() . ") 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=''" ( = ->getOne( []['filter_attr_name'] = = "SELECT a.attr_id, MIN(a.goods_attr_id ) AS goods_id, a.attr_value AS attr_value FROM " . ->table('goods_attr') . " AS a, " . ->table('goods') . " AS g" . " WHERE ( OR " . get_extension_goods() . ') AND g.goods_id = a.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. " AND a.attr_id='' ". " GROUP BY a.attr_value" = ->getAll( = ( = 0; < (); ++ [] = !([]) ? [] : 0 [] = 0; = ('.', []['attr_list'][0]['attr_value'] = ['all_attribute' []['attr_list'][0]['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>, 'price_max'=>, 'filter_attr'=>), ['cat_name' []['attr_list'][0]['selected'] = ([]) ? 1 : 0 ( => = + 1 [] = ['goods_id']; = ('.', []['attr_list'][]['attr_value'] = ['attr_value' []['attr_list'][]['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>, 'price_max'=>, 'filter_attr'=>), ['cat_name' (!([]) AND [] == ['goods_id']) { []['attr_list'][]['selected'] = 1 []['attr_list'][]['selected'] = 0 ->assign('filter_attr_list', (!( = "SELECT DISTINCT(b.goods_id) FROM " . ->table('goods_attr') . " AS a, " . ->table('goods_attr') . " AS b " . "WHERE " = ( => ) { (() && !=0 = . "b.attr_value = a.attr_value AND b.attr_id = " . [] ." AND a.goods_attr_id = " . = ->getColCached( .= ' AND ' . db_create_in(, 'g.goods_id' assign_template('c', ( = assign_ur_here(, ->assign('page_title', ['title']); ->assign('ur_here', ['ur_here']); ->assign('categories', get_categories_tree()); ->assign('helps', get_shop_help()); ->assign('top_goods', get_top10()); ->assign('show_marketprice', ['show_marketprice']); ->assign('category', ->assign('brand_id', ->assign('price_max', ->assign('price_min', ->assign('filter_attr', ->assign('feed_url', (['rewrite'] == 1) ? "feed-c.xml" : 'feed.php?cat=' . ); ( > 0 ['all'] = ('brand_id' => 0, 'brand_name' => ['_LANG']['all_goods'], 'brand_logo' => '', 'goods_num' => '', 'url' => build_uri('category', ('cid'=>), ['cat_name' } = = (, get_brands(, 'category' ->assign('data_dir', DATA_DIR); ->assign('brand_list', ->assign('promotion_info', get_promotion_info()); = (!( ->assign('vote_id', ['id' ->assign('vote', ['content' ->assign('best_goods', get_category_recommend_goods('best', , , , , ->assign('promotion_goods', get_category_recommend_goods('promote', , , , , ->assign('hot_goods', get_category_recommend_goods('hot', , , , , = get_cagtegory_goods_count(, , , , = (> 0) ? ( / ) : 1 ( > = = category_get_goods(, , , , , , , , ( == 'grid' (() % 2 != 0 [] = ->assign('goods_list', ); ->assign('category', ); ->assign('script_name', 'category'); assign_pager('category', , , , , , , '', , , , , ); assign_dynamic('category'); ->display('category.dwt', ?> 查看category.php全部代码

 

1)第一步,首先,文件一开头,一定是接收前台页面发送过来的各种POST和GET参数了,这里主要还是指地址栏GET方式传过来的参数了。

  
 
  = (['page'])   && (['page'])  > 0 ? (['page'])  : 1  = (['page_size'])  && (['page_size']) > 0 ? (['page_size']) : 10  = (['brand']) && (['brand']) > 0 ? (['brand']) : 0  = (['price_max']) && (['price_max']) > 0 ? (['price_max']) : 0  = (['price_min']) && (['price_min']) > 0 ? (['price_min']) : 0  = (['filter_attr']) ? ((['filter_attr'])) : '0'  = (  = () ? '' : ('.', ( 
 
  = ['show_order_type'] == '0' ? 'list' : (['show_order_type'] == '1' ? 'grid' : 'text'  = ['sort_order_method'] == '0' ? 'DESC' : 'ASC'    = ['sort_order_type'] == '0' ? 'goods_id' : (['sort_order_type'] == '1' ? 'shop_price' : 'last_update' 
   = ((['sort'])  && (((['sort'])), ('goods_id', 'shop_price', 'last_update'))) ? (['sort'])  :   = ((['order']) && (((['order'])), ('ASC', 'DESC')))                              ? (['order']) :    = ((['display']) && (((['display'])), ('list', 'grid', 'text'))) ? (['display'])  : ((['ECS']['display']) ? ['ECS']['display'] :    = (, ('list', 'grid', 'text')) ?  : 'text' ('ECS[display]', , gmtime() + 86400 * 7);

 

= get_children( = get_cat_info(); View Code

 

(['grade'] == 0 && ['parent_id'] != 0) { ['grade'] = get_parent_grade(); (['grade'] > 1 = "SELECT min(g.shop_price) AS min, max(g.shop_price) as max ". " FROM " . ->table('goods'). " AS g ". " WHERE ( OR " . get_extension_goods() . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 ' = ->getRow( = 0.0001 (=-2; <= (['max']); ++ *= 10 = ((['max'] - ['min']) / (['grade']) / ) * ( == 0 = ( = 1; ['min'] > * ; ++ ( = 1; ['min'] > * (-1) + * ; ++ ['min'] = * (-1) + * ( - 1 (; ['max'] >= * ; ++ ['max'] = * () + * ( - 1 = "SELECT (FLOOR((g.shop_price - [min]) / )) AS sn, COUNT(*) AS goods_num ". " FROM " . ->table('goods') . " AS g ". " WHERE ( OR " . get_extension_goods() . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. " GROUP BY sn " = ->getAll( ( => = + 1 []['goods_num'] = ['goods_num' []['start'] = ['min'] + ( * ['sn' []['end'] = ['min'] + ( * (['sn'] + 1 []['price_range'] = []['start'] . '&nbsp;-&nbsp;' . []['end' []['formated_start'] = price_format([]['start' []['formated_end'] = price_format([]['end' []['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>[]['start'], 'price_max'=> []['end'], 'filter_attr'=>), ['cat_name' ((['price_min']) && []['start'] == && []['end'] == []['selected'] = 1 []['selected'] = 0 [0]['start'] = 0 [0]['end'] = 0 [0]['price_range'] = ['all_attribute' [0]['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>0, 'price_max'=> 0, 'filter_attr'=>), ['cat_name' [0]['selected'] = () ? 1 : 0 ->assign('price_grade', View Code

 

= "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ". "FROM " . ['ecs']->table('brand') . "AS b, ". ['ecs']->table('goods') . " AS g LEFT JOIN ". ['ecs']->table('goods_cat') . " AS gc ON g.goods_id = gc.goods_id " . "WHERE g.brand_id = b.brand_id AND ( OR " . 'gc.cat_id ' . db_create_in((((), (cat_list(, 0, ))))) . ") 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" = ['db']->getAll( ( => = + 1 []['brand_name'] = ['brand_name' []['url'] = build_uri('category', ('cid' => , 'bid' => ['brand_id'], 'price_min'=>, 'price_max'=> , 'filter_attr'=>), ['cat_name' ( == []['brand_id' []['selected'] = 1 } []['selected'] = 0 [0]['brand_name'] = ['all_attribute' [0]['url'] = build_uri('category', ('cid' => , 'bid' => 0, 'price_min'=>, 'price_max'=> , 'filter_attr'=>), ['cat_name' [0]['selected'] = () ? 1 : 0 ->assign('brands', View Code

 

= ''; (['filter_attr'] > 0 = (',', ['filter_attr']); = ( => = "SELECT a.attr_name FROM " . ->table('attribute') . " AS a, " . ->table('goods_attr') . " AS ga, " . ->table('goods') . " AS g WHERE ( OR " . get_extension_goods() . ") 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=''" ( = ->getOne( []['filter_attr_name'] = = "SELECT a.attr_id, MIN(a.goods_attr_id ) AS goods_id, a.attr_value AS attr_value FROM " . ->table('goods_attr') . " AS a, " . ->table('goods') . " AS g" . " WHERE ( OR " . get_extension_goods() . ') AND g.goods_id = a.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '. " AND a.attr_id='' ". " GROUP BY a.attr_value" = ->getAll( = ( = 0; < (); ++ [] = !([]) ? [] : 0 [] = 0; = ('.', []['attr_list'][0]['attr_value'] = ['all_attribute' []['attr_list'][0]['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>, 'price_max'=>, 'filter_attr'=>), ['cat_name' []['attr_list'][0]['selected'] = ([]) ? 1 : 0 ( => = + 1 [] = ['goods_id']; = ('.', []['attr_list'][]['attr_value'] = ['attr_value' []['attr_list'][]['url'] = build_uri('category', ('cid'=>, 'bid'=>, 'price_min'=>, 'price_max'=>, 'filter_attr'=>), ['cat_name' (!([]) AND [] == ['goods_id']) { []['attr_list'][]['selected'] = 1 []['attr_list'][]['selected'] = 0 ->assign('filter_attr_list', (!( = "SELECT DISTINCT(b.goods_id) FROM " . ->table('goods_attr') . " AS a, " . ->table('goods_attr') . " AS b " . "WHERE " = ( => ) { (() && !=0 = . "b.attr_value = a.attr_value AND b.attr_id = " . [] ." AND a.goods_attr_id = " . = ->getColCached( .= ' AND ' . db_create_in(, 'g.goods_id' View Code

 

assign_template('c', ( = assign_ur_here(, ->assign('page_title', ['title']); ->assign('ur_here', ['ur_here']); ->assign('categories', get_categories_tree()); ->assign('helps', get_shop_help()); ->assign('top_goods', get_top10()); ->assign('show_marketprice', ['show_marketprice']); ->assign('category', ->assign('brand_id', ->assign('price_max', ->assign('price_min', ->assign('filter_attr', ->assign('feed_url', (['rewrite'] == 1) ? "feed-c.xml" : 'feed.php?cat=' . ); ( > 0 ['all'] = ('brand_id' => 0, 'brand_name' => ['_LANG']['all_goods'], 'brand_logo' => '', 'goods_num' => '', 'url' => build_uri('category', ('cid'=>), ['cat_name' } = = (, get_brands(, 'category' ->assign('data_dir', DATA_DIR); ->assign('brand_list', ->assign('promotion_info', get_promotion_info()); = (!( ->assign('vote_id', ['id' ->assign('vote', ['content' ->assign('best_goods', get_category_recommend_goods('best', , , , , ->assign('promotion_goods', get_category_recommend_goods('promote', , , , , ->assign('hot_goods', get_category_recommend_goods('hot', , , , , = get_cagtegory_goods_count(, , , , = (> 0) ? ( / ) : 1 ( > = = category_get_goods(, , , , , , , , ( == 'grid' (() % 2 != 0 [] = ->assign('goods_list', ); ->assign('category', ); ->assign('script_name', 'category'); assign_pager('category', , , , , , , '', , , , , ); assign_dynamic('category'); ->display('category.dwt', ); View Code

 

 

 

不过,我也学到了一些东西,具体如下:

① 对Ecshop商品主要数据表的设计有了了解。(下一篇会简单介绍)

② 原来这里的要对商品的那些属性进行筛选,并不是程序自动处理,而是管理员后台指定的。

③ 价格区间的计算,是按照一定的算法计算出来的,比较智能,但数字不太好看(另外一种策略,是自己后台为每一个商品分类,都指定一个价格区间,也是可以的。)

④ 品牌、价格区间和属性,都是按照一定的原则从数据库抽取出来的。即,这些说有的分类或者属性下,必须是有商品的,才会把它获取出来。比如,如果颜色为黑色的属性下面是没有任何商品的,那么黑色这个属性,就不应该显示出来。其他依次类推。

⑤ 对于一些较为复杂的mysql语句查询,有了一些了解(希望不断提高啦。。)

 

以上,是小弟做的一些小小的分析和总结,我经验还不丰富啊,有哪一些不对的地方和不足,希望大家指正,我会虚心学习和接受,谢谢啦!!

 

 

 

 

 

 

 

 

www.phpzy.comtrue/php/6042.htmlTechArticle【PHP开源产品】Ecshop的商品筛选功能实现分析之一(主要对category.php进行分析) 一、首先,说明一下为什么要对category.php文件进行分析。 (1)原因如下: ①个人对商城类商品筛选功能...

相关文章

相关频道:

PHP之友评论

今天推荐