目錄
一、首先,说明一下为什么要对category.php文件进行分析。
二、然后,我们首先看一下现在需求是如何的?(多条件筛选,请参考京东、苏宁、国美等)
首頁 php教程 php手册 【PHP开源产品】Ecshop的商品筛选功能实现分析之一

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

Jun 06, 2016 pm 07:43 PM
ecshop php 產品 功能 商品 實現 開源 篩選

一、首先,说明一下为什么要对category.php文件进行分析。 原因如下: ①个人对商城类商品筛选功能的实现比较好奇; ②对商城中关于商品的数据表设计比较感兴趣。(该功能涉及到与数据库的交互,而且与数据库中数据表的设计好坏有一定的联系); ③多条件(

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

原因如下:

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

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

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

 

希望达到的目的是:

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

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

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

 

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

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

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

 

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

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

 

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

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

 

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

 

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

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

2)然后,我就通过该地址来访问主页,并查看属于导航栏中“GSM手机”分类下的商品。如下:

访问地址为:http://demo.ecshop.com/category.php?id=3   

结果页面为:

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

 

那么,此时的访问,会罗列出,属于“GSM手机”分类下(即cat_id=3)的所有商品,因为目前还没有对商品进行多筛选。

 

 

访问地址为:  http://demo.ecshop.com/category.php?id=3&brand=1&price_min=0&price_max=0

结果页面为:

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

 

如果我选择了多条件搜索,看截图:

访问地址为: http://demo.ecshop.com/category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.0.160.0

结果页面为:

【PHP开源产品】Ecshop的商品筛选功能实现分析之一

 

 

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

猜想1:随着用户每一次点击条件(属性)进行商品筛选时,搜索地址栏会变化,为什么地址栏会变化,

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

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

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

 

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

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

 

1.点击这里,查看全部代码的分析过程。

【PHP开源产品】Ecshop的商品筛选功能实现分析之一【PHP开源产品】Ecshop的商品筛选功能实现分析之一

<span>  1</span> <span>php
</span><span>  2</span> <span>/*</span><span>*
</span><span>  3</span> <span> * 分析首页 商品分类页面category.php的实现方法
</span><span>  4</span> <span> * ECSHOP 2.7.2 商品分类
</span><span>  5</span>  <span>*/</span>
<span>  6</span> <span>define</span>('IN_ECS', <span>true</span><span>);
</span><span>  7</span> <span>require</span>(<span>dirname</span>(<span>__FILE__</span>) . '/includes/init.php'<span>);
</span><span>  8</span> <span>if</span> ((DEBUG_MODE & 2) != 2<span>) {
</span><span>  9</span>     <span>$smarty</span>->caching = <span>true</span><span>;
</span><span> 10</span> <span>}
</span><span> 11</span> 
<span> 12</span> <span>//</span><span>====> 请求地址栏:http://localhost/category.php?id=3&brand=1&price_min=200&price_max=1700&filter_attr=163.216.160.186
</span><span> 13</span> <span>//====> 1.获取分类id</span>
<span> 14</span> <span>/*</span><span> 获得请求的分类 ID </span><span>*/</span>
<span> 15</span> <span>if</span> (<span>isset</span>(<span>$_REQUEST</span>['id'<span>])) {
</span><span> 16</span>     <span>$cat_id</span> = <span>intval</span>(<span>$_REQUEST</span>['id'<span>]);
</span><span> 17</span> <span>}
</span><span> 18</span> <span>elseif</span> (<span>isset</span>(<span>$_REQUEST</span>['category'<span>])) {
</span><span> 19</span>     <span>$cat_id</span> = <span>intval</span>(<span>$_REQUEST</span>['category'<span>]);
</span><span> 20</span> } <span>else</span><span> {
</span><span> 21</span>     <span>/*</span><span> 如果分类ID为0,则返回首页 </span><span>*/</span>
<span> 22</span>     ecs_header("Location: ./\n"<span>);
</span><span> 23</span>     <span>exit</span><span>;
</span><span> 24</span> <span>}
</span><span> 25</span> 
<span> 26</span> <span>//</span><span>====> 2.首先获取所有GET和POST中,可用于搜索的参数的值。
</span><span> 27</span> <span>//====> 若没有此参数,则说明,并没有用此参数来搜索,默认要给它一个默认值。</span>
<span> 28</span> <span>/*</span><span> 初始化分页信息 </span><span>*/</span>
<span> 29</span> <span>$page</span> = <span>isset</span>(<span>$_REQUEST</span>['page'])   && <span>intval</span>(<span>$_REQUEST</span>['page'])  > 0 ? <span>intval</span>(<span>$_REQUEST</span>['page'])  : 1<span>;
</span><span> 30</span> <span>$size</span> = <span>isset</span>(<span>$_CFG</span>['page_size'])  && <span>intval</span>(<span>$_CFG</span>['page_size']) > 0 ? <span>intval</span>(<span>$_CFG</span>['page_size']) : 10<span>;
</span><span> 31</span> <span>$brand</span> = <span>isset</span>(<span>$_REQUEST</span>['brand']) && <span>intval</span>(<span>$_REQUEST</span>['brand']) > 0 ? <span>intval</span>(<span>$_REQUEST</span>['brand']) : 0<span>;
</span><span> 32</span> <span>$price_max</span> = <span>isset</span>(<span>$_REQUEST</span>['price_max']) && <span>intval</span>(<span>$_REQUEST</span>['price_max']) > 0 ? <span>intval</span>(<span>$_REQUEST</span>['price_max']) : 0<span>;
</span><span> 33</span> <span>$price_min</span> = <span>isset</span>(<span>$_REQUEST</span>['price_min']) && <span>intval</span>(<span>$_REQUEST</span>['price_min']) > 0 ? <span>intval</span>(<span>$_REQUEST</span>['price_min']) : 0<span>;
</span><span> 34</span> <span>$filter_attr_str</span> = <span>isset</span>(<span>$_REQUEST</span>['filter_attr']) ? <span>htmlspecialchars</span>(<span>trim</span>(<span>$_REQUEST</span>['filter_attr'])) : '0'<span>;
</span><span> 35</span> <span>$filter_attr_str</span> = <span>urldecode</span>(<span>$filter_attr_str</span><span>);
</span><span> 36</span> <span>$filter_attr</span> = <span>empty</span>(<span>$filter_attr_str</span>) ? '' : <span>explode</span>('.', <span>trim</span>(<span>$filter_attr_str</span><span>));
</span><span> 37</span> 
<span> 38</span> <span>/*</span><span> 排序、显示方式以及类型 </span><span>*/</span>
<span> 39</span> <span>$default_display_type</span> = <span>$_CFG</span>['show_order_type'] == '0' ? 'list' : (<span>$_CFG</span>['show_order_type'] == '1' ? 'grid' : 'text'<span>);
</span><span> 40</span> <span>$default_sort_order_method</span> = <span>$_CFG</span>['sort_order_method'] == '0' ? 'DESC' : 'ASC'<span>;
</span><span> 41</span> <span>$default_sort_order_type</span>   = <span>$_CFG</span>['sort_order_type'] == '0' ? 'goods_id' : (<span>$_CFG</span>['sort_order_type'] == '1' ? 'shop_price' : 'last_update'<span>);
</span><span> 42</span> 
<span> 43</span> <span>$sort</span>  = (<span>isset</span>(<span>$_REQUEST</span>['sort'])  && <span>in_array</span>(<span>trim</span>(<span>strtolower</span>(<span>$_REQUEST</span>['sort'])), <span>array</span>('goods_id', 'shop_price', 'last_update'))) ? <span>trim</span>(<span>$_REQUEST</span>['sort'])  : <span>$default_sort_order_type</span><span>;
</span><span> 44</span> <span>$order</span> = (<span>isset</span>(<span>$_REQUEST</span>['order']) && <span>in_array</span>(<span>trim</span>(<span>strtoupper</span>(<span>$_REQUEST</span>['order'])), <span>array</span>('ASC', 'DESC')))                              ? <span>trim</span>(<span>$_REQUEST</span>['order']) : <span>$default_sort_order_method</span><span>;
</span><span> 45</span> <span>$display</span>  = (<span>isset</span>(<span>$_REQUEST</span>['display']) && <span>in_array</span>(<span>trim</span>(<span>strtolower</span>(<span>$_REQUEST</span>['display'])), <span>array</span>('list', 'grid', 'text'))) ? <span>trim</span>(<span>$_REQUEST</span>['display'])  : (<span>isset</span>(<span>$_COOKIE</span>['ECS']['display']) ? <span>$_COOKIE</span>['ECS']['display'] : <span>$default_display_type</span><span>);
</span><span> 46</span> <span>$display</span>  = <span>in_array</span>(<span>$display</span>, <span>array</span>('list', 'grid', 'text')) ? <span>$display</span> : 'text'<span>;
</span><span> 47</span> <span>setcookie</span>('ECS[display]', <span>$display</span>, gmtime() + 86400 * 7<span>);
</span><span> 48</span> 
<span> 49</span> <span>/*</span><span> 页面的缓存ID </span><span>*/</span>
<span> 50</span> <span>$cache_id</span> = <span>sprintf</span>('%X', <span>crc32</span>(<span>$cat_id</span> . '-' . <span>$display</span> . '-' . <span>$sort</span>  .'-' . <span>$order</span>  .'-' . <span>$page</span> . '-' . <span>$size</span> . '-' . <span>$_SESSION</span>['user_rank'] . '-' .
<span> 51</span>         <span>$_CFG</span>['lang'] .'-'. <span>$brand</span>. '-' . <span>$price_max</span> . '-' .<span>$price_min</span> . '-' . <span>$filter_attr_str</span><span>));
</span><span> 52</span> 
<span> 53</span> <span>/*</span><span> 如果页面没有被缓存则重新获取页面的内容 </span><span>*/</span>
<span> 54</span> <span>if</span> (!<span>$smarty</span>->is_cached('category.dwt', <span>$cache_id</span><span>)) {
</span><span> 55</span> <span>//</span><span>====> 3.把该栏目下的所有子栏目id获取,如果没有子栏目,则是自身。
</span><span> 56</span> <span>//===> TABLE:ecs_category
</span><span> 57</span> <span>//====> RETURN:id=3 => g.cat_id IN ('3')  或 id=6 => g.cat_id IN ('6','8','9','11','7')
</span><span> 58</span> <span>//====> 说明:ecshop的特点是,顶级栏目下也可以添加商品,所以会把顶级栏目id也放在数组里面</span>
<span> 59</span> <span>$children</span> = get_children(<span>$cat_id</span><span>);  
</span><span> 60</span> 
<span> 61</span> <span>//</span><span>====> 4.获得该分类的相关信息。如:分类名称、价格分级、筛选属性、父id
</span><span> 62</span> <span>//===> TABLE:ecs_category
</span><span> 63</span> <span>//====> RETURN:Array ( [cat_name] => GSM手机 [keywords] => [cat_desc] => [style] => [grade] => 4 [filter_attr] => 185,189,173,178 [parent_id] => 1 )</span>
<span> 64</span> <span>$cat</span> = get_cat_info(<span>$cat_id</span><span>);   
</span><span> 65</span> 
<span> 66</span> <span>//</span><span>===> 5.如果有品牌筛选brand参数,那么获取出该品牌名称
</span><span> 67</span> <span>//===> TABLE:ecs_brand
</span><span> 68</span> <span>//===> SQL:SELECT brand_name FROM `ecshop`.`ecs_brand` WHERE brand_id = '1'
</span><span> 69</span> <span>//====> RETURN:诺基亚</span>
<span> 70</span>  <span>/*</span><span> 赋值固定内容 </span><span>*/</span>
<span> 71</span> <span>if</span> (<span>$brand</span> > 0<span>) {
</span><span> 72</span>     <span>$sql</span> = "SELECT brand_name FROM " .<span>$GLOBALS</span>['ecs']->table('brand'). " WHERE brand_id = '<span>$brand</span>'"<span>;
</span><span> 73</span>     <span>$brand_name</span> = <span>$db</span>->getOne(<span>$sql</span><span>);
</span><span> 74</span> } <span>else</span><span> {
</span><span> 75</span>     <span>$brand_name</span> = ''<span>;
</span><span> 76</span> <span>}
</span><span> 77</span> 
<span> 78</span> 
<span> 79</span> <span>//</span><span>/>>================开始---商品价格区间处理==================>>///
</span><span> 80</span> <span>//===> 6.获取该分类cat的价格分级:
</span><span> 81</span> <span>//===> ①如果价格分级=0,那么获取直接父类的价格分级。(Ⅰ如果父类价格也=0,那么就是不用价格分级 )
</span><span> 82</span> <span>//===> ②如果价格分级!=0,那么就是自身的价格分级。
</span><span> 83</span> <span>//===> TABLE:ecs_category
</span><span> 84</span> <span>//===> RETURN:$cat['grade']=4</span>
<span> 85</span> <span>/*</span><span> 获取价格分级 </span><span>*/</span>
<span> 86</span> <span>if</span> (<span>$cat</span>['grade'] == 0  && <span>$cat</span>['parent_id'] != 0) { <span>//</span><span>  ==>如果价格分级为空,但是它还有上级分类,那么取直接上级的价格分级等数</span>
<span> 87</span>     <span>$cat</span>['grade'] = get_parent_grade(<span>$cat_id</span>); <span>//</span><span>如果当前分类级别为空,取最近的上级分类</span>
<span> 88</span> <span>}
</span><span> 89</span> 
<span> 90</span> <span>//</span><span>===> 7.对价格区间进行划分。 ecshop的划分方法,是根据算法来的,比较复杂。
</span><span> 91</span> <span>//===> 如果价格分级>1,那么就执行价格区间划分</span>
<span> 92</span> <span>if</span> (<span>$cat</span>['grade'] > 1<span>) {
</span><span> 93</span>     <span>/*</span><span> 需要价格分级 </span><span>*/</span>
<span> 94</span> 
<span> 95</span>     <span>/*</span>
<span> 96</span> <span>     算法思路:
</span><span> 97</span> <span>    1、当分级大于1时,进行价格分级
</span><span> 98</span> <span>    2、取出该类下商品价格的最大值、最小值
</span><span> 99</span> <span>    3、根据商品价格的最大值来计算商品价格的分级数量级:
</span><span>100</span> <span>    价格范围(不含最大值)    分级数量级
</span><span>101</span> <span>    0-0.1                   0.001
</span><span>102</span> <span>    0.1-1                   0.01
</span><span>103</span> <span>    1-10                    0.1
</span><span>104</span> <span>    10-100                  1
</span><span>105</span> <span>    100-1000                10
</span><span>106</span> <span>    1000-10000              100
</span><span>107</span> <span>    4、计算价格跨度:
</span><span>108</span> <span>    取整((最大值-最小值) / (价格分级数) / 数量级) * 数量级
</span><span>109</span> <span>    5、根据价格跨度计算价格范围区间
</span><span>110</span> <span>    6、查询数据库
</span><span>111</span> 
<span>112</span> <span>    可能存在问题:
</span><span>113</span> <span>    1、
</span><span>114</span> <span>    由于价格跨度是由最大值、最小值计算出来的
</span><span>115</span> <span>    然后再通过价格跨度来确定显示时的价格范围区间
</span><span>116</span> <span>    所以可能会存在价格分级数量不正确的问题
</span><span>117</span> <span>    该问题没有证明
</span><span>118</span> <span>    2、
</span><span>119</span> <span>    当价格=最大值时,分级会多出来,已被证明存在
</span><span>120</span>     <span>*/</span>
<span>121</span>     
<span>122</span>     <span>//</span><span>===> 获得当前分类下商品价格的最大值、最小值
</span><span>123</span> <span>    //===> 获得所有扩展分类属于指定分类的所有商品ID ,其中goods_id = 16的商品的扩展属于分类3
</span><span>124</span> <span>    //===> TABLE:ecs_goods 和 ecs_goods_cat
</span><span>125</span> <span>    //===> 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
</span><span>126</span> <span>    //===> RETURN:Array ( [min] => 280.00 [max] => 5999.00 ) </span>
<span>127</span>     <span>$sql</span> = "SELECT min(g.shop_price) AS min, max(g.shop_price) as max ".
<span>128</span>             " FROM " . <span>$ecs</span>->table('goods'). " AS g ".
<span>129</span>             " WHERE (<span>$children</span> OR " . get_extension_goods(<span>$children</span>) . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1  '<span>;
</span><span>130</span>     <span>$row</span> = <span>$db</span>->getRow(<span>$sql</span><span>);
</span><span>131</span> 
<span>132</span>     
<span>133</span>     <span>//</span><span>===> 按照公式计算出最低价格和最高价格、以及价格跨度
</span><span>134</span> <span>    //===============↓↓↓先不做讨论===============
</span><span>135</span> <span>    // 取得价格分级最小单位级数,比如,千元商品最小以100为级数</span>
<span>136</span>     <span>$price_grade</span> = 0.0001<span>;
</span><span>137</span>     <span>for</span>(<span>$i</span>=-2; <span>$i</span>log10(<span>$row</span>['max']); <span>$i</span>++<span>) {
</span><span>138</span>         <span>$price_grade</span> *= 10<span>;
</span><span>139</span> <span>    }
</span><span>140</span>     
<span>141</span>     <span>//</span><span>价格跨度</span>
<span>142</span>     <span>$dx</span> = <span>ceil</span>((<span>$row</span>['max'] - <span>$row</span>['min']) / (<span>$cat</span>['grade']) / <span>$price_grade</span>) * <span>$price_grade</span><span>;
</span><span>143</span>     <span>if</span>(<span>$dx</span> == 0<span>) {
</span><span>144</span>         <span>$dx</span> = <span>$price_grade</span><span>;
</span><span>145</span> <span>    }
</span><span>146</span>     
<span>147</span>     <span>for</span>(<span>$i</span> = 1; <span>$row</span>['min'] > <span>$dx</span> * <span>$i</span>; <span>$i</span> ++<span>);
</span><span>148</span>     
<span>149</span>         <span>for</span>(<span>$j</span> = 1; <span>$row</span>['min'] > <span>$dx</span> * (<span>$i</span>-1) + <span>$price_grade</span> * <span>$j</span>; <span>$j</span>++<span>);
</span><span>150</span>         <span>$row</span>['min'] = <span>$dx</span> * (<span>$i</span>-1) + <span>$price_grade</span> * (<span>$j</span> - 1<span>);
</span><span>151</span>     
<span>152</span>         <span>for</span>(; <span>$row</span>['max'] >= <span>$dx</span> * <span>$i</span>; <span>$i</span> ++<span>);
</span><span>153</span>         <span>$row</span>['max'] = <span>$dx</span> * (<span>$i</span>) + <span>$price_grade</span> * (<span>$j</span> - 1<span>);
</span><span>154</span> 
<span>155</span>         <span>//</span><span>===>这里打印最高价格和最低价格:$row=>Array ( [min] => 200 [max] => 6200 ) 
</span><span>156</span> <span>        //===>这里打印价格跨度:$dx = 1500
</span><span>157</span>         
<span>158</span> <span>        //===============先不做讨论↑↑↑==================//
</span><span>159</span>     
<span>160</span> 
<span>161</span> <span>        //===> 根据商品的价格、价格区间的最低价格、以及价格跨度,计算该商品价格属于哪一个区间内。
</span><span>162</span> <span>        //===> 获取属于该价格区间内的商品的数量、获取sn则属于哪一个区间sn=0为200-1700、sn=1为1700-3200、sn=3为4700-6200。
</span><span>163</span> <span>        //===> 因为没有商品价格属于第二区间,则不存在sn=2,那么3200-4700则没有任何商品
</span><span>164</span> <span>        //===> TABLE:ecs_goods 和 ecs_goods_cat
</span><span>165</span> <span>        //===> 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 
</span><span>166</span> <span>        //===>RETURN:Array ( [0] => Array ( [sn] => 0 [goods_num] => 6 ) [1] => Array ( [sn] => 1 [goods_num] => 5 ) [2] => Array ( [sn] => 3 [goods_num] => 1 ) ) </span>
<span>167</span>         <span>$sql</span> = "SELECT (FLOOR((g.shop_price - <span>$row</span>[min]) / <span>$dx</span>)) AS sn, COUNT(*) AS goods_num  ".
<span>168</span>                 " FROM " . <span>$ecs</span>->table('goods') . " AS g ".
<span>169</span>                 " WHERE (<span>$children</span> OR " . get_extension_goods(<span>$children</span>) . ') AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '.
<span>170</span>                 " GROUP BY sn "<span>;
</span><span>171</span>         <span>$price_grade</span> = <span>$db</span>->getAll(<span>$sql</span><span>);
</span><span>172</span> 
<span>173</span>         
<span>174</span>         <span>//</span><span>===> 根据价格等级price_grade,计算真正的价格区间。
</span><span>175</span> <span>        //===> 方法build_uri()重要:要为每一个价格区间,生成一个url超链接,以备前台点击搜索用
</span><span>176</span> <span>        //===> 并根据价格参数,判断该区间,是否是当前被搜索的区间
</span><span>177</span> <span>        //===> 把价格区间,注入模板,供前台使用
</span><span>178</span> <span>        //===> 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 ) ) </span>
<span>179</span>         <span>foreach</span> (<span>$price_grade</span> <span>as</span> <span>$key</span>=><span>$val</span><span>) {
</span><span>180</span>             <span>$temp_key</span> = <span>$key</span> + 1<span>;
</span><span>181</span>             <span>$price_grade</span>[<span>$temp_key</span>]['goods_num'] = <span>$val</span>['goods_num'<span>];
</span><span>182</span>             <span>$price_grade</span>[<span>$temp_key</span>]['start'] = <span>$row</span>['min'] + <span>round</span>(<span>$dx</span> * <span>$val</span>['sn'<span>]);
</span><span>183</span>             <span>$price_grade</span>[<span>$temp_key</span>]['end'] = <span>$row</span>['min'] + <span>round</span>(<span>$dx</span> * (<span>$val</span>['sn'] + 1<span>));
</span><span>184</span>             <span>$price_grade</span>[<span>$temp_key</span>]['price_range'] = <span>$price_grade</span>[<span>$temp_key</span>]['start'] . ' - ' . <span>$price_grade</span>[<span>$temp_key</span>]['end'<span>];
</span><span>185</span>             <span>$price_grade</span>[<span>$temp_key</span>]['formated_start'] = price_format(<span>$price_grade</span>[<span>$temp_key</span>]['start'<span>]);
</span><span>186</span>             <span>$price_grade</span>[<span>$temp_key</span>]['formated_end'] = price_format(<span>$price_grade</span>[<span>$temp_key</span>]['end'<span>]);
</span><span>187</span>             <span>$price_grade</span>[<span>$temp_key</span>]['url'] = build_uri('category', <span>array</span>('cid'=><span>$cat_id</span>, 'bid'=><span>$brand</span>, 'price_min'=><span>$price_grade</span>[<span>$temp_key</span>]['start'], 'price_max'=> <span>$price_grade</span>[<span>$temp_key</span>]['end'], 'filter_attr'=><span>$filter_attr_str</span>), <span>$cat</span>['cat_name'<span>]);
</span><span>188</span>             <span>/*</span><span> 判断价格区间是否被选中 </span><span>*/</span>
<span>189</span>             <span>if</span> (<span>isset</span>(<span>$_REQUEST</span>['price_min']) && <span>$price_grade</span>[<span>$temp_key</span>]['start'] == <span>$price_min</span> && <span>$price_grade</span>[<span>$temp_key</span>]['end'] == <span>$price_max</span><span>) {
</span><span>190</span>                 <span>$price_grade</span>[<span>$temp_key</span>]['selected'] = 1<span>;
</span><span>191</span> <span>            }
</span><span>192</span>             <span>else</span><span> {
</span><span>193</span>                 <span>$price_grade</span>[<span>$temp_key</span>]['selected'] = 0<span>;
</span><span>194</span> <span>            }
</span><span>195</span> <span>        }
</span><span>196</span>         <span>//</span><span>补充一个选择全部的类型的数组</span>
<span>197</span>         <span>$price_grade</span>[0]['start'] = 0<span>;
</span><span>198</span>         <span>$price_grade</span>[0]['end'] = 0<span>;
</span><span>199</span>         <span>$price_grade</span>[0]['price_range'] = <span>$_LANG</span>['all_attribute'<span>];
</span><span>200</span>         <span>$price_grade</span>[0]['url'] = build_uri('category', <span>array</span>('cid'=><span>$cat_id</span>, 'bid'=><span>$brand</span>, 'price_min'=>0, 'price_max'=> 0, 'filter_attr'=><span>$filter_attr_str</span>), <span>$cat</span>['cat_name'<span>]);
</span><span>201</span>         <span>$price_grade</span>[0]['selected'] = <span>empty</span>(<span>$price_max</span>) ? 1 : 0<span>;
</span><span>202</span>         <span>//</span><span>把价格区间数组,注入模板文件</span>
<span>203</span>         <span>$smarty</span>->assign('price_grade',     <span>$price_grade</span><span>);
</span><span>204</span> <span>    }
</span><span>205</span>     <span>//</span><span>/
<span>206</span>     
<span>207</span>     
<span>208</span>     <span>//</span><span>/>>================开始---商品品牌处理==================>>///
</span><span>209</span> <span>    //====> ???db_create_in(array_unique(array_merge(array($cat_id), array_keys(cat_list($cat_id, 0, false))))) . ")
</span><span>210</span> <span>    //===> 品牌筛选功能:把该栏目下(其中包括扩展分类下的商品),所有商品的品牌获取,但不能重复。
</span><span>211</span> <span>    //===> 品牌下有商品并且商品状态正常,才能把该品牌取出。没有商品的品牌不能取出
</span><span>212</span> <span>    //===> TABLE:ecs_brand、ecs_goods 和 ecs_goods_cat
</span><span>213</span> <span>    //===> 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
</span><span>214</span> <span>    //===> 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 ) ) </span>
<span>215</span>     <span>/*</span><span> 品牌筛选 </span><span>*/</span>
<span>216</span>     <span>$sql</span> = "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ".
<span>217</span>             "FROM " . <span>$GLOBALS</span>['ecs']->table('brand') . "AS b, ".
<span>218</span>             <span>$GLOBALS</span>['ecs']->table('goods') . " AS g LEFT JOIN ". <span>$GLOBALS</span>['ecs']->table('goods_cat') . " AS gc ON g.goods_id = gc.goods_id " .
<span>219</span>             "WHERE g.brand_id = b.brand_id AND (<span>$children</span> OR " . 'gc.cat_id ' . db_create_in(<span>array_unique</span>(<span>array_merge</span>(<span>array</span>(<span>$cat_id</span>), <span>array_keys</span>(cat_list(<span>$cat_id</span>, 0, <span>false</span>))))) . ") AND b.is_show = 1 " .
<span>220</span>             " AND g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 ".
<span>221</span>             "GROUP BY b.brand_id HAVING goods_num > 0 ORDER BY b.sort_order, b.brand_id ASC"<span>;
</span><span>222</span>     <span>$brands</span> = <span>$GLOBALS</span>['db']->getAll(<span>$sql</span><span>);
</span><span>223</span> 
<span>224</span>     <span>//</span><span>===> 把该分类下所有商品的品牌,组合成数组,给前台调用
</span><span>225</span> <span>    //===> 方法build_uri()重要:要为每品牌,生成一个url超链接,以备前台点击搜索用
</span><span>226</span> <span>    //===> 把数组注入模板文件
</span><span>227</span> <span>    //====! 这样一种组织数组的方式,有它的缺陷:就是说不能够把每一个品牌下面的,商品的数量保存下来,同时也会有一些无用的数据,掺杂其中。
</span><span>228</span> <span>    //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 ) ) </span>
<span>229</span>     <span>foreach</span> (<span>$brands</span> <span>AS</span> <span>$key</span> => <span>$val</span><span>) {
</span><span>230</span>         <span>$temp_key</span> = <span>$key</span> + 1<span>;
</span><span>231</span>         <span>$brands</span>[<span>$temp_key</span>]['brand_name'] = <span>$val</span>['brand_name'<span>];
</span><span>232</span>         <span>$brands</span>[<span>$temp_key</span>]['url'] = build_uri('category', <span>array</span>('cid' => <span>$cat_id</span>, 'bid' => <span>$val</span>['brand_id'], 'price_min'=><span>$price_min</span>, 'price_max'=> <span>$price_max</span>, 'filter_attr'=><span>$filter_attr_str</span>), <span>$cat</span>['cat_name'<span>]);
</span><span>233</span>         <span>/*</span><span> 判断品牌是否被选中 </span><span>*/</span>
<span>234</span>         <span>if</span> (<span>$brand</span> == <span>$brands</span>[<span>$key</span>]['brand_id'<span>]) {
</span><span>235</span>             <span>$brands</span>[<span>$temp_key</span>]['selected'] = 1<span>;
</span><span>236</span>         } <span>else</span><span> {
</span><span>237</span>             <span>$brands</span>[<span>$temp_key</span>]['selected'] = 0<span>;
</span><span>238</span> <span>        }
</span><span>239</span> <span>    }
</span><span>240</span>     <span>//</span><span>补充一个选择全部品牌的数组</span>
<span>241</span>     <span>$brands</span>[0]['brand_name'] = <span>$_LANG</span>['all_attribute'<span>];
</span><span>242</span>     <span>$brands</span>[0]['url'] = build_uri('category', <span>array</span>('cid' => <span>$cat_id</span>, 'bid' => 0, 'price_min'=><span>$price_min</span>, 'price_max'=> <span>$price_max</span>, 'filter_attr'=><span>$filter_attr_str</span>), <span>$cat</span>['cat_name'<span>]);
</span><span>243</span>     <span>$brands</span>[0]['selected'] = <span>empty</span>(<span>$brand</span>) ? 1 : 0<span>;
</span><span>244</span>     <span>//</span><span>把品牌数组注入模板</span>
<span>245</span>     <span>$smarty</span>->assign('brands', <span>$brands</span><span>);
</span><span>246</span>     <span>//</span><span>/
<span>247</span>     
<span>248</span>     
<span>249</span> 
<span>250</span>     <span>//</span><span>/>>==================开始---商品属性处理==================>>///</span>
<span>251</span>     <span>/*</span><span> 属性筛选 </span><span>*/</span>
<span>252</span>     <span>$ext</span> = ''; <span>//</span><span>商品查询条件扩展</span>
<span>253</span>     <span>if</span> (<span>$cat</span>['filter_attr'] > 0<span>) {
</span><span>254</span>         <span>//</span><span>===>需要筛选的属性,是人工在后台添加的,存放在ecs_category 表的中 filter_attr字段里面,格式如:185,189,120,190
</span><span>255</span> <span>        //===>RETURN:Array ( [0] => 185 [1] => 189 [2] => 173 [3] => 178 )</span>
<span>256</span>         <span>$cat_filter_attr</span> = <span>explode</span>(',', <span>$cat</span>['filter_attr']);       <span>//</span><span>提取出此分类的筛选属性
</span><span>257</span>         
<span>258</span> <span>        //===> 然后,对每一个属性(此属性是主属性,下面还有子属性),循环进行操作
</span><span>259</span> <span>        //===> ①获取该属性的属性名
</span><span>260</span> <span>        //===> ②获取该属性的所有子属性(子属性必须是有被商品在使用的,不然,不要将其显示出来)
</span><span>261</span> <span>        //===> 意义:因为该属性涉及到搜索参数,如果该属性下本身没有商品,那么就没有显示出来的意义了。
</span><span>262</span> <span>        //===> 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] => 黑色 ) ) </span>
<span>263</span>         <span>$all_attr_list</span> = <span>array</span><span>();
</span><span>264</span>         <span>foreach</span> (<span>$cat_filter_attr</span> <span>AS</span> <span>$key</span> => <span>$value</span><span>) { 
</span><span>265</span>             <span>$sql</span> = "SELECT a.attr_name FROM " . <span>$ecs</span>->table('attribute') . " AS a, " . <span>$ecs</span>->table('goods_attr') . " AS ga, " . <span>$ecs</span>->table('goods') . " AS g WHERE (<span>$children</span> OR " . get_extension_goods(<span>$children</span>) . ") 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='<span>$value</span>'"<span>;
</span><span>266</span>             <span>if</span>(<span>$temp_name</span> = <span>$db</span>->getOne(<span>$sql</span><span>)) {
</span><span>267</span>                 <span>//</span><span>获取该属性名(主属性)</span>
<span>268</span>                 <span>$all_attr_list</span>[<span>$key</span>]['filter_attr_name'] = <span>$temp_name</span><span>;  
</span><span>269</span>                 
<span>270</span>                 <span>//</span><span>获取该属性的所有子属性(子属性必须是有被商品在使用的,不然,不要将其显示出来)
</span><span>271</span> <span>                //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] => 黑色 ) )</span>
<span>272</span>                 <span>$sql</span> = "SELECT a.attr_id, MIN(a.goods_attr_id ) AS goods_id, a.attr_value AS attr_value FROM " . <span>$ecs</span>->table('goods_attr') . " AS a, " . <span>$ecs</span>->table('goods') .
<span>273</span>                 " AS g" .
<span>274</span>                 " WHERE (<span>$children</span> OR " . get_extension_goods(<span>$children</span>) . ') AND g.goods_id = a.goods_id AND g.is_delete = 0 AND g.is_on_sale = 1 AND g.is_alone_sale = 1 '.
<span>275</span>                 " AND a.attr_id='<span>$value</span>' ".
<span>276</span>                 " GROUP BY a.attr_value"<span>;
</span><span>277</span>                 <span>$attr_list</span> = <span>$db</span>->getAll(<span>$sql</span><span>);
</span><span>278</span>     
<span>279</span>                 <span>//</span><span>如果后台指定该分类下,用于搜索的属性的组数,是跟地址栏中filter_attr=0.0.0.0  中0的个数是一样的,而且顺序都是一样的
</span><span>280</span> <span>                //第一个0,表示第一组属性中,它选择了哪一个子属性,以此类推
</span><span>281</span> <span>                //获取当前url中已选择属性的值,并保留在数组中
</span><span>282</span> <span>                //!这里要作循环,是因为避免属性为0或者空时,导致出错,因为直接把$filter_attr 赋值给 $temp_arrt_url_arr会出错。
</span><span>283</span> <span>                //RETURN:Array ( [0] => 163 [1] => 216 [2] => 160 [3] => 186 ) </span>
<span>284</span>                 <span>$temp_arrt_url_arr</span> = <span>array</span><span>();
</span><span>285</span>                 <span>for</span> (<span>$i</span> = 0; <span>$i</span> count</span>(<span>$cat_filter_attr</span>); <span>$i</span>++<span>) {     
</span><span>286</span>                     <span>$temp_arrt_url_arr</span>[<span>$i</span>] = !<span>empty</span>(<span>$filter_attr</span>[<span>$i</span>]) ? <span>$filter_attr</span>[<span>$i</span>] : 0<span>;  
</span><span>287</span> <span>                }
</span><span>288</span>     
<span>289</span>                 <span>//</span><span>这里是该属性下,选择全部时的数组形式
</span><span>290</span> <span>                //哪一个属性的值为0,即说明用户选择的是该属性的全部选项
</span><span>291</span> <span>                //为“全部”生成url
</span><span>292</span> <span>                //DATA:Array ( [0] => 0 [1] => 216 [2] => 160 [3] => 186 ) </span>
<span>293</span>                 <span>$temp_arrt_url_arr</span>[<span>$key</span>] = 0;    <span>//</span><span>“全部”的信息生成 </span>
<span>294</span>                 <span>$temp_arrt_url</span> = <span>implode</span>('.', <span>$temp_arrt_url_arr</span><span>);
</span><span>295</span>                 <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][0]['attr_value'] = <span>$_LANG</span>['all_attribute'<span>];
</span><span>296</span>                 <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][0]['url'] = build_uri('category', <span>array</span>('cid'=><span>$cat_id</span>, 'bid'=><span>$brand</span>, 'price_min'=><span>$price_min</span>, 'price_max'=><span>$price_max</span>, 'filter_attr'=><span>$temp_arrt_url</span>), <span>$cat</span>['cat_name'<span>]);
</span><span>297</span>                 <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][0]['selected'] = <span>empty</span>(<span>$filter_attr</span>[<span>$key</span>]) ? 1 : 0<span>;
</span><span>298</span>     
<span>299</span>                 <span>//</span><span>循环计算子属性的相关数组:属性值,属性是否选择,属性的url
</span><span>300</span> <span>                //判断当前子属性,是否被选中状态
</span><span>301</span> <span>                //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 ) ) ) ) </span>
<span>302</span>                 <span>foreach</span> (<span>$attr_list</span> <span>as</span> <span>$k</span> => <span>$v</span><span>) {
</span><span>303</span>                     <span>$temp_key</span> = <span>$k</span> + 1<span>;
</span><span>304</span>                     <span>$temp_arrt_url_arr</span>[<span>$key</span>] = <span>$v</span>['goods_id'];       <span>//</span><span>为url中代表当前筛选属性的位置变量赋值,并生成以‘.’分隔的筛选属性字符串</span>
<span>305</span>                     <span>$temp_arrt_url</span> = <span>implode</span>('.', <span>$temp_arrt_url_arr</span><span>);
</span><span>306</span>     
<span>307</span>                     <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][<span>$temp_key</span>]['attr_value'] = <span>$v</span>['attr_value'<span>];
</span><span>308</span>                     <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][<span>$temp_key</span>]['url'] = build_uri('category', <span>array</span>('cid'=><span>$cat_id</span>, 'bid'=><span>$brand</span>, 'price_min'=><span>$price_min</span>, 'price_max'=><span>$price_max</span>, 'filter_attr'=><span>$temp_arrt_url</span>), <span>$cat</span>['cat_name'<span>]);
</span><span>309</span>     
<span>310</span>                     <span>if</span> (!<span>empty</span>(<span>$filter_attr</span>[<span>$key</span>]) AND <span>$filter_attr</span>[<span>$key</span>] == <span>$v</span>['goods_id']) { <span>//</span><span>处理已被选择的子属性</span>
<span>311</span>                         <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][<span>$temp_key</span>]['selected'] = 1<span>;
</span><span>312</span> <span>                    }
</span><span>313</span>                     <span>else</span><span> {
</span><span>314</span>                         <span>$all_attr_list</span>[<span>$key</span>]['attr_list'][<span>$temp_key</span>]['selected'] = 0<span>;
</span><span>315</span> <span>                    }
</span><span>316</span> <span>                }
</span><span>317</span> <span>            }
</span><span>318</span> <span>        }
</span><span>319</span>         <span>//</span><span>为模板注入变量</span>
<span>320</span>         <span>$smarty</span>->assign('filter_attr_list',  <span>$all_attr_list</span><span>);
</span><span>321</span>         
<span>322</span>         
<span>323</span>         <span>/*</span><span> 扩展商品查询条件 </span><span>*/</span>
<span>324</span>         <span>if</span> (!<span>empty</span>(<span>$filter_attr</span><span>)) {
</span><span>325</span>             <span>$ext_sql</span> = "SELECT DISTINCT(b.goods_id) FROM " . <span>$ecs</span>->table('goods_attr') . " AS a, " . <span>$ecs</span>->table('goods_attr') . " AS b " .  "WHERE "<span>;
</span><span>326</span>             <span>$ext_group_goods</span> = <span>array</span><span>();
</span><span>327</span>             <span>foreach</span> (<span>$filter_attr</span> <span>AS</span> <span>$k</span> => <span>$v</span>) { <span>//</span><span> 查出符合所有筛选属性条件的商品id */</span>
<span>328</span>                 <span>if</span> (<span>is_numeric</span>(<span>$v</span>) && <span>$v</span> !=0<span> ) {
</span><span>329</span>                     <span>$sql</span> = <span>$ext_sql</span> . "b.attr_value = a.attr_value AND b.attr_id = " . <span>$cat_filter_attr</span>[<span>$k</span>] ." AND a.goods_attr_id = " . <span>$v</span><span>;
</span><span>330</span>                     <span>$ext_group_goods</span> = <span>$db</span>->getColCached(<span>$sql</span><span>);
</span><span>331</span>                     <span>$ext</span> .= ' AND ' . db_create_in(<span>$ext_group_goods</span>, 'g.goods_id'<span>);
</span><span>332</span> <span>                }
</span><span>333</span> <span>            }
</span><span>334</span> <span>        }
</span><span>335</span> <span>    } 
</span><span>336</span>     <span>//</span><span>/<span>337</span>     
<span>338</span> <span>    //向模板,载入一些前台,必备的变量和常量</span>
<span>339</span>     assign_template('c', <span>array</span>(<span>$cat_id</span><span>));
</span><span>340</span>     
<span>341</span>     <span>//</span><span>RETURN:Array ( [title] => 夏新_GSM手机_手机类型_ECSHOP演示站 - Powered by ECShop [ur_here] => 首页 > 手机类型 > GSM手机 > 夏新 )</span>
<span>342</span>     <span>$position</span> = assign_ur_here(<span>$cat_id</span>, <span>$brand_name</span><span>);
</span><span>343</span>     
<span>344</span>     <span>$smarty</span>->assign('page_title',       <span>$position</span>['title']);    <span>//</span><span> 页面标题</span>
<span>345</span>     <span>$smarty</span>->assign('ur_here',          <span>$position</span>['ur_here']);  <span>//</span><span> 当前位置</span>
<span>346</span>     
<span>347</span>     <span>$smarty</span>->assign('categories',       get_categories_tree(<span>$cat_id</span>)); <span>//</span><span> 分类树</span>
<span>348</span>     <span>$smarty</span>->assign('helps',            get_shop_help());              <span>//</span><span> 网店帮助</span>
<span>349</span>     <span>$smarty</span>->assign('top_goods',        get_top10());                  <span>//</span><span> 销售排行</span>
<span>350</span>     <span>$smarty</span>->assign('show_marketprice', <span>$_CFG</span>['show_marketprice']); <span>//</span><span>是否显示市场价</span>
<span>351</span>     <span>$smarty</span>->assign('category',         <span>$cat_id</span><span>);
</span><span>352</span>     <span>$smarty</span>->assign('brand_id',         <span>$brand</span><span>);
</span><span>353</span>     <span>$smarty</span>->assign('price_max',        <span>$price_max</span><span>);
</span><span>354</span>     <span>$smarty</span>->assign('price_min',        <span>$price_min</span><span>);
</span><span>355</span>     <span>$smarty</span>->assign('filter_attr',      <span>$filter_attr_str</span><span>);
</span><span>356</span>     <span>$smarty</span>->assign('feed_url',         (<span>$_CFG</span>['rewrite'] == 1) ? "feed-c<span>$cat_id</span>.xml" : 'feed.php?cat=' . <span>$cat_id</span>); <span>//</span><span> RSS URL</span>
<span>357</span>     
<span>358</span>     <span>if</span> (<span>$brand</span> > 0<span>) {
</span><span>359</span>         <span>$arr</span>['all'] = <span>array</span>('brand_id'  => 0,
<span>360</span>                 'brand_name'    => <span>$GLOBALS</span>['_LANG']['all_goods'],
<span>361</span>                 'brand_logo'    => '',
<span>362</span>                 'goods_num'     => '',
<span>363</span>                 'url'           => build_uri('category', <span>array</span>('cid'=><span>$cat_id</span>), <span>$cat</span>['cat_name'<span>])
</span><span>364</span> <span>        );
</span><span>365</span>     } <span>else</span><span> {
</span><span>366</span>         <span>$arr</span> = <span>array</span><span>();
</span><span>367</span> <span>    }
</span><span>368</span>     
<span>369</span>     <span>$brand_list</span> = <span>array_merge</span>(<span>$arr</span>, get_brands(<span>$cat_id</span>, 'category'<span>));
</span><span>370</span>     <span>$smarty</span>->assign('data_dir',    DATA_DIR); <span>//</span><span>网站data目录</span>
<span>371</span>     <span>$smarty</span>->assign('brand_list',      <span>$brand_list</span><span>);
</span><span>372</span>     <span>$smarty</span>->assign('promotion_info', get_promotion_info()); <span>//</span><span>获取推荐信息</span>
<span>373</span>     
<span>374</span>     <span>/*</span><span> 调查 </span><span>*/</span>
<span>375</span>     <span>$vote</span> =<span> get_vote();
</span><span>376</span>     <span>if</span> (!<span>empty</span>(<span>$vote</span><span>)) {
</span><span>377</span>         <span>$smarty</span>->assign('vote_id',     <span>$vote</span>['id'<span>]);
</span><span>378</span>         <span>$smarty</span>->assign('vote',        <span>$vote</span>['content'<span>]);
</span><span>379</span> <span>    }
</span><span>380</span>     
<span>381</span>     <span>//</span><span>获取最热销、推荐和最热卖商品</span>
<span>382</span>     <span>$smarty</span>->assign('best_goods',      get_category_recommend_goods('best', <span>$children</span>, <span>$brand</span>, <span>$price_min</span>, <span>$price_max</span>, <span>$ext</span><span>));
</span><span>383</span>     <span>$smarty</span>->assign('promotion_goods', get_category_recommend_goods('promote', <span>$children</span>, <span>$brand</span>, <span>$price_min</span>, <span>$price_max</span>, <span>$ext</span><span>));
</span><span>384</span>     <span>$smarty</span>->assign('hot_goods',       get_category_recommend_goods('hot', <span>$children</span>, <span>$brand</span>, <span>$price_min</span>, <span>$price_max</span>, <span>$ext</span><span>));
</span><span>385</span>     <span>//</span><span>获取该前状态下,商品的数量</span>
<span>386</span>     <span>$count</span> = get_cagtegory_goods_count(<span>$children</span>, <span>$brand</span>, <span>$price_min</span>, <span>$price_max</span>, <span>$ext</span><span>);
</span><span>387</span>     <span>//</span><span>最大页数</span>
<span>388</span>     <span>$max_page</span> = (<span>$count</span>> 0) ? <span>ceil</span>(<span>$count</span> / <span>$size</span>) : 1<span>;
</span><span>389</span>     <span>if</span> (<span>$page</span> > <span>$max_page</span><span>) {
</span><span>390</span>         <span>$page</span> = <span>$max_page</span><span>;
</span><span>391</span> <span>    }
</span><span>392</span>     
<span>393</span>     <span>//</span><span>获取该栏目下的所有商品</span>
<span>394</span>     <span>$goodslist</span> = category_get_goods(<span>$children</span>, <span>$brand</span>, <span>$price_min</span>, <span>$price_max</span>, <span>$ext</span>, <span>$size</span>, <span>$page</span>, <span>$sort</span>, <span>$order</span><span>);
</span><span>395</span>     
<span>396</span>     <span>//</span><span>判断选择了列表还是图片方式显示方式</span>
<span>397</span>     <span>if</span>(<span>$display</span> == 'grid'<span>) {
</span><span>398</span>         <span>if</span>(<span>count</span>(<span>$goodslist</span>) % 2 != 0<span>) {
</span><span>399</span>             <span>$goodslist</span>[] = <span>array</span><span>();
</span><span>400</span> <span>        }
</span><span>401</span> <span>    }
</span><span>402</span>     
<span>403</span>     <span>$smarty</span>->assign('goods_list',       <span>$goodslist</span>); <span>//</span><span>注入商品列表</span>
<span>404</span>     <span>$smarty</span>->assign('category',         <span>$cat_id</span>); <span>//</span><span>注入分类id</span>
<span>405</span>     <span>$smarty</span>->assign('script_name', 'category'); <span>//</span><span>注入该脚本的名称</span>
<span>406</span>     
<span>407</span>     assign_pager('category',            <span>$cat_id</span>, <span>$count</span>, <span>$size</span>, <span>$sort</span>, <span>$order</span>, <span>$page</span>, '', <span>$brand</span>, <span>$price_min</span>, <span>$price_max</span>, <span>$display</span>, <span>$filter_attr_str</span>); <span>//</span><span> 分页</span>
<span>408</span>     assign_dynamic('category'); <span>//</span><span> 动态内容</span>
<span>409</span> <span>}
</span><span>410</span> <span>$smarty</span>->display('category.dwt', <span>$cache_id</span><span>);
</span><span>411</span> ?></span></span>
登入後複製
查看category.php全部代码

 

2.分步分析其实现过程:

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

<span> 1</span> <span>//</span><span>====> 2.首先获取所有GET和POST中,可用于搜索的参数的值。
</span><span> 2</span> <span>//====> 若没有此参数,则说明,并没有用此参数来搜索,默认要给它一个默认值。</span>
<span> 3</span> <span>/*</span><span> 初始化分页信息 </span><span>*/</span>
<span> 4</span> <span>$page</span> = <span>isset</span>(<span>$_REQUEST</span>['page'])   && <span>intval</span>(<span>$_REQUEST</span>['page'])  > 0 ? <span>intval</span>(<span>$_REQUEST</span>['page'])  : 1<span>;
</span><span> 5</span> <span>$size</span> = <span>isset</span>(<span>$_CFG</span>['page_size'])  && <span>intval</span>(<span>$_CFG</span>['page_size']) > 0 ? <span>intval</span>(<span>$_CFG</span>['page_size']) : 10<span>;
</span><span> 6</span> <span>$brand</span> = <span>isset</span>(<span>$_REQUEST</span>['brand']) && <span>intval</span>(<span>$_REQUEST</span>['brand']) > 0 ? <span>intval</span>(<span>$_REQUEST</span>['brand']) : 0<span>;
</span><span> 7</span> <span>$price_max</span> = <span>isset</span>(<span>$_REQUEST</span>['price_max']) && <span>intval</span>(<span>$_REQUEST</span>['price_max']) > 0 ? <span>intval</span>(<span>$_REQUEST</span>['price_max']) : 0<span>;
</span><span> 8</span> <span>$price_min</span> = <span>isset</span>(<span>$_REQUEST</span>['price_min']) && <span>intval</span>(<span>$_REQUEST</span>['price_min']) > 0 ? <span>intval</span>(<span>$_REQUEST</span>['price_min']) : 0<span>;
</span><span> 9</span> <span>$filter_attr_str</span> = <span>isset</span>(<span>$_REQUEST</span>['filter_attr']) ? <span>htmlspecialchars</span>(<span>trim</span>(<span>$_REQUEST</span>['filter_attr'])) : '0'<span>;
</span><span>10</span> <span>$filter_attr_str</span> = <span>urldecode</span>(<span>$filter_attr_str</span><span>);
</span><span>11</span> <span>$filter_attr</span> = <span>empty</span>(<span>$filter_attr_str</span>) ? '' : <span>explode</span>('.', <span>trim</span>(<span>$filter_attr_str</span><span>));
</span><span>12</span> 
<span>13</span> <span>/*</span><span> 排序、显示方式以及类型 </span><span>*/</span>
<span>14</span> <span>$default_display_type</span> = <span>$_CFG</span>['show_order_type'] == '0' ? 'list' : (<span>$_CFG</span>['show_order_type'] == '1' ? 'grid' : 'text'<span>);
</span><span>15</span> <span>$default_sort_order_method</span> = <span>$_CFG</span>['sort_order_method'] == '0' ? 'DESC' : 'ASC'<span>;
</span><span>16</span> <span>$default_sort_order_type</span>   = <span>$_CFG</span>['sort_order_type'] == '0' ? 'goods_id' : (<span>$_CFG</span>['sort_order_type'] == '1' ? 'shop_price' : 'last_update'<span>);
</span><span>17</span> 
<span>18</span> <span>$sort</span>  = (<span>isset</span>(<span>$_REQUEST</span>['sort'])  && <span>in_array</span>(<span>trim</span>(<span>strtolower</span>(<span>$_REQUEST</span>['sort'])), <span>array</span>('goods_id', 'shop_price', 'last_update'))) ? <span>trim</span>(<span>$_REQUEST</span>['sort'])  : <span>$default_sort_order_type</span><span>;
</span><span>19</span> <span>$order</span> = (<span>isset</span>(<span>$_REQUEST</span>['order']) && <span>in_array</span>(<span>trim</span>(<span>strtoupper</span>(<span>$_REQUEST</span>['order'])), <span>array</span>('ASC', 'DESC')))                              ? <span>trim</span>(<span>$_REQUEST</span>['order']) : <span>$default_sort_order_method</span><span>;
</span><span>20</span> <span>$display</span>  = (<span>isset</span>(<span>$_REQUEST</span>['display']) && <span>in_array</span>(<span>trim</span>(<span>strtolower</span>(<span>$_REQUEST</span>['display'])), <span>array</span>('list', 'grid', 'text'))) ? <span>trim</span>(<span>$_REQUEST</span>['display'])  : (<span>i</span>
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

我後悔之前不知道的 7 個 PHP 函數 我後悔之前不知道的 7 個 PHP 函數 Nov 13, 2024 am 09:42 AM

如果您是經驗豐富的PHP 開發人員,您可能會感覺您已經在那裡並且已經完成了。操作

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

See all articles