各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案

Str Tom,为分享PHP技术和解决方案,贡献一份自己的力量!
收藏本站(不迷路),每天更新好文章!
当前位置:首页 > CMS教程 > phpcms

phpcms筛选功能(经典无错)---汇总网上各种版本!

管理员 2022-08-28
phpcms
318
phpcms的筛选功能,网上有各种版本,但是多多少少都会有点问题,不是很完美,下面我总结网上各种版本,加上自己的研究,得出一个算是比较全的一个资料,既可以分页,也可以分栏目!

第一步:后台添加字段

添加字段:
后台-->内容-->内容相关设置-->模型管理-->文章模型-->字段管理-->添加字段-->如下图示例:



第二步:增加扩展函数:

将以下代码添加到 phpcms/libs/functions/extention.func.php 文件
为了防止错误,也可以点此下载
https://www.pweb123.com/uploadfile/2016/0703/20160703094036307.rar

  1. /** 
  2.  *  extention.func.php 用户自定义函数库 
  3.  * 
  4.  * @copyright                        (C) 2005-2010 PHPCMS 
  5.  * @license                           http://www.phpcms.cn/license/ 
  6.  * @lastmodify                        2010-10-27 
  7.  */ 
  8.  
  9. /********************实现筛选功能************************/ 
  10.  /** 
  11.  * 通过指定keyid形式显示所有联动菜单 
  12.  * @param  $keyid 菜单主id 
  13.  * @param  $linkageid  联动菜单id,0调用顶级 
  14.  * @param  $modelid 模型id 
  15.  * @param  $fieldname  字段名称 
  16.  */ 
  17. function show_linkage($keyid, $linkageid = 0, $modelid = '', $fieldname='zone') { 
  18.     $datas = $infos = $array = array(); 
  19.     $keyid = intval($keyid); 
  20.     $linkageid = intval($linkageid); 
  21.     //当前菜单id 
  22.     $field_value = intval($_GET[$fieldname]); 
  23.     $urlrule = structure_filters_url($fieldname,$array,1,$modelid); 
  24.     if($keyid == 0) return false
  25.     $datas = getcache($keyid,'linkage'); 
  26.     $infos = $datas['data']; 
  27.  
  28.     foreach($infos as $k=>$v){ 
  29.         if($v['parentid']==$field_value){ 
  30.             $array[$k]['name'] = $v['name']; 
  31.             $array[$k]['value'] = $k; 
  32.             $array[$k]['url'] = str_replace('{$'.$fieldname.'}',$k,$urlrule); 
  33.             $array[$k]['menu'] = $field_value == $k ? ''.$v['name'].'' : '.$array[$k]['url'].'>'.$v['name'].'' ; 
  34.             } 
  35.             } 
  36.             return $array; 
  37.             } 
  38. function structure_filters_url($fieldname,$array=array(),$type = 1,$modelid) { 
  39.     if(empty($array)) { 
  40.         $array = $_GET; 
  41.         } else { 
  42.             $array = array_merge($_GET,$array); 
  43.             } 
  44.         //TODO 
  45.         $fields = getcache('model_field_'.$modelid,'model'); 
  46.         if(is_array($fields) && !empty($fields)) { 
  47.             ksort($fields); 
  48.             foreach ($fields as $_v=>$_k) { 
  49.                 if($_k['filtertype'] || $_k['rangetype']) { 
  50.                     if(strpos(URLRULE,'.html') === FALSE) $urlpars .= '&'.$_v.'={$'.$_v.'}'
  51.                     else $urlpars .= '-{$'.$_v.'}'
  52.                     } 
  53.                     } 
  54.                     } 
  55.         //后期增加伪静态等其他url规则管理,apache伪静态支持9个参数 
  56.         if(strpos(URLRULE,'.html') === FALSE) $urlrule =APP_PATH.'index.php?m=content&c=index&a=lists&catid={$catid}'.$urlpars.'&page={$page}' ; 
  57.         else $urlrule =APP_PATH.'list-{$catid}'.$urlpars.'-{$page}.html'
  58.         //根据get传值构造URL 
  59.         if (is_array($array)) foreach ($array as $_k=>$_v) { 
  60.             if($_k=='page') $_v=1; 
  61.             if($type == 1) if($_k==$fieldname) continue
  62.             $_findme[] = '/{$'.$_k.'}/'
  63.             $_replaceme[] = $_v; 
  64.             } 
  65.      //type 模式的时候,构造排除该字段名称的正则 
  66.         if($type==1) $filter = '(?!'.$fieldname.'.)'
  67.         $_findme[] = '/{$'.$filter.'([a-z0-9_]+)}/'
  68.         $_replaceme[] = ''
  69.         $urlrule = preg_replace($_findme, $_replaceme, $urlrule); 
  70.         return         $urlrule; 
  71.         } 
  72. /** 
  73.  * 生成分类信息中的筛选菜单 
  74.  * @param $field   字段名称 
  75.  * @param $modelid  模型ID 
  76.  */ 
  77. function filters($field,$modelid,$diyarr = array()) { 
  78.     $fields = getcache('model_field_'.$modelid,'model'); 
  79.     $options = empty($diyarr) ?  explode("n",$fields[$field]['options']) : $diyarr; 
  80.     $field_value = intval($_GET[$field]); 
  81.     foreach($options as $_k) { 
  82.         $v = explode("|",$_k); 
  83.         $k = trim($v[1]); 
  84.         $option[$k]['name'] = $v[0]; 
  85.         $option[$k]['value'] = $k; 
  86.         $option[$k]['url'] = structure_filters_url($field,array($field=>$k),2,$modelid); 
  87.         $option[$k]['menu'] = $field_value == $k ? ''.$v[0].'' : '.$option[$k]['url'].'>'.$v[0].'' ; 
  88.     } 
  89.     $all['name'] = '全部'
  90.     $all['url'] = structure_filters_url($field,array($field=>''),2,$modelid); 
  91.     $all['menu'] = $field_value == '' ? ''.$all['name'].'' : '.$all['url'].'>'.$all['name'].''
  92.  
  93.     array_unshift($option,$all); 
  94.     return $option; 
  95.  
  96. /** 
  97.  * 获取联动菜单层级 
  98.  * @param  $keyid     联动菜单分类id 
  99.  * @param  $linkageid 菜单id 
  100.  * @param  $leveltype 获取类型 parentid 获取父级id child 获取时候有子栏目 arrchildid 获取子栏目数组 
  101.  */ 
  102. function get_linkage_level($keyid,$linkageid,$leveltype = 'parentid') { 
  103.     $child_arr = $childs = array(); 
  104.     $leveltypes = array('parentid','child','arrchildid','arrchildinfo'); 
  105.     $datas = getcache($keyid,'linkage'); 
  106.     $infos = $datas['data']; 
  107.     if (in_array($leveltype, $leveltypes)) { 
  108.         if($leveltype == 'arrchildinfo') { 
  109.             $child_arr = explode(',',$infos[$linkageid]['arrchildid']); 
  110.             foreach ($child_arr as $r) { 
  111.                 $childs[] = $infos[$r]; 
  112.             } 
  113.             return $childs; 
  114.         } else { 
  115.             return $infos[$linkageid][$leveltype]; 
  116.         } 
  117.     }     
  118.  
  119. // 根据linkageid递归到父级 
  120. function get_parent_url($modelid,$field,$linkageid=0,$array = array()){ 
  121.     $modelid = intval($modelid); 
  122.     if(!$modelid || empty($field)) return false
  123.     $fields = getcache('model_field_'.$modelid,'model'); 
  124.     $keyid = $fields[$field]['linkageid']; 
  125.     $datas = getcache($keyid,'linkage'); 
  126.     $infos = $datas['data']; 
  127.                  
  128.     if(empty($linkageid)){ 
  129.         $linkageid = intval($_GET[$field]); 
  130.         if(!$linkageid) return false
  131.         } 
  132.          
  133.         $urlrule = structure_filters_url($field,array(),1,$modelid); 
  134.         $urlrule = str_replace('{$'.$field.'}',$infos[$linkageid]['parentid'],$urlrule); 
  135.         array_unshift($array,array('name'=> $infos[$linkageid]['name'],'url'=>$urlrule)); 
  136.         if($infos[$linkageid]['parentid']){ 
  137.             return get_parent_url($modelid,$field,$infos[$linkageid]['parentid'],$array); 
  138.             } 
  139.             return $array; 
  140.             } 
  141. /** 
  142.  * 构造筛选时候的sql语句 
  143.  */ 
  144. function structure_filters_sql($modelid) { 
  145.     $sql = $fieldname = $min = $max = ''
  146.     $fieldvalue = array(); 
  147.     $modelid = intval($modelid); 
  148.     $model =  getcache('model','commons'); 
  149.     $fields = getcache('model_field_'.$modelid,'model'); 
  150.     $fields_key = array_keys($fields); 
  151.     //TODO 
  152.     $sql = '`status` = '99''
  153.  
  154.          
  155.     foreach ($_GET as $k=>$r) { 
  156.         if(in_array($k,$fields_key) && intval($r)!=0 && ($fields[$k]['filtertype'] || $fields[$k]['rangetype']|| $fields[$k]['boxtype'])) { 
  157.             if($fields[$k]['formtype'] == 'linkage') { 
  158.                 $datas = getcache($fields[$k]['linkageid'],'linkage'); 
  159.                 $infos = $datas['data']; 
  160.                 if($infos[$r]['arrchildid']) { 
  161.                     $sql .=  ' AND `'.$k.'` in('.$infos[$r]['arrchildid'].')'
  162.                 } 
  163.             } elseif($fields[$k]['rangetype']) { 
  164.                         if(is_numeric($r)) { 
  165.                             $sql .=" AND `$k` = '$r'"
  166.                         } else { 
  167.                                 $fieldvalue = explode('_',$r); 
  168.                                 $min = intval($fieldvalue[0]); 
  169.                                 $max = $fieldvalue[1] ? intval($fieldvalue[1]) : 999999; 
  170.                                 $sql .=" AND `$k` >= '$min' AND  `$k` < '$max'"
  171.                         } 
  172.             }elseif($fields[$k]['boxtype']=='checkbox') { 
  173.                    $sql .=" AND `$k` like '%,$r,%'"
  174.  
  175.             } else { 
  176.                    $sql .=" AND `$k` = '$r'"
  177.             } 
  178.         } 
  179.     } 
  180.    // echo $sql; 
  181.    return $sql; 
  182.  
  183. /** 
  184.  * 分页,如去掉则分页会有问题 
  185.  */ 
  186. function makeurlrule() { 
  187.     if(strpos(URLRULE,'.html') === FALSE) { 
  188.         return url_par('page={$'.'page}'); 
  189.     } 
  190.     else { 
  191.         $url = preg_replace('/-[0-9]+.html$/','-{$page}.html',get_url()); 
  192.         return $url; 
  193.     } 
  194.  
  195.  
  196. /********************实现前台输出“选项名称”功能************************/ 
  197. /** 
  198. * 根据box类型字段获取显示名称 
  199. * @param $field 字段名称 
  200. * @param $value 字段值 
  201. * @param $modelid 字段所在模型id 
  202. */ 
  203. function box($field, $value, $modelid='') { 
  204.         $fields = getcache('model_field_'.$modelid,'model'); 
  205.         extract(string2array($fields[$field]['setting'])); 
  206.         $options = explode("n",$fields[$field]['options']); 
  207.         foreach($options as $_k) { 
  208.                 $v = explode("|",$_k); 
  209.                 $k = trim($v[1]); 
  210.                 $option[$k] = $v[0]; 
  211.         } 
  212.         $string = ''
  213.         switch($fields[$field]['boxtype']) { 
  214.                         case 'radio'
  215.                                 $string = $option[$value]; 
  216.                         break
  217.                         case 'checkbox'
  218.                                 $value_arr = explode(',',$value); 
  219.                                 foreach($value_arr as $_v) { 
  220.                                         if($_v) $string .= $option[$_v].' 、'
  221.                                 } 
  222.                         break
  223.  
  224.                         case 'select'
  225.                                 $string = $option[$value]; 
  226.                         break
  227.  
  228.                         case 'multiple'
  229.                                 $value_arr = explode(',',$value); 
  230.                                 foreach($value_arr as $_v) { 
  231.                                         if($_v) $string .= $option[$_v].' 、'
  232.                                 } 
  233.                         break
  234.                 } 
  235.                         return $string; 
  236. ?> 
(注:makeurlrule函数对分页是否能传递相关参数很重要!

第三步:前台模板调用

  1. {php $sql = structure_filters_sql($modelid);}  
  2. {php $urlrule = makeurlrule()} 
  3. {pc:content action="lists" catid="$catid" where="$sql"  modelid="$modelid" num="10" page="$page" moreinfo="1"  urlrule="$urlrule" return="data" } 
  4. {loop $data $r} 
  5. ........
  6. {/loop} 
  7. {/pc} 


一般网上都是到这一步就没有了,没有了......
但是你会发现,还有很多问题,下面就来解决


第一个问题:list条件下加入where后其他条件失效的问题


之前的一篇文章:解决lists标签中,加上where后其他条件失效的问题,其他条件失效了,如catid,thumb等等,也就是无法获取当前栏目的信息,而是把整个栏目下的所有文章都调用出来了!
打开/phpcms/modules/content/classes/目录下的content_tag.class.php这个文件,把下面的代码(大概第63行)
  1. if(isset($data['where'])) {   
  2. $sql = $data['where'];   
  3. else {   
  4. $thumb = intval($data['thumb']) ? " AND thumb != ''" : '';   
  5. if($this->category[$catid]['child']) {   
  6. $catids_str = $this->category[$catid]['arrchildid'];   
  7. $pos = strpos($catids_str,',')+1;   
  8. $catids_str = substr($catids_str, $pos);   
  9. $sql = "status=99 AND catid IN ($catids_str)".$thumb;   
  10. else {   
  11. $sql = "status=99 AND catid='$catid'".$thumb;   
  12. }   
  13. }   
替换为下面的代码即可。
  1. if(isset($data['where'])) {   
  2. $where = (isset($data['where'])&&(!empty($data['where'])))?' AND '.$data['where']:'';   
  3. $thumb = intval($data['thumb']) ? " AND thumb != ''" : '';   
  4. if($this->category[$catid]['child']) {   
  5. $catids_str = $this->category[$catid]['arrchildid'];   
  6. $pos = strpos($catids_str,',')+1;   
  7. $catids_str = substr($catids_str, $pos);   
  8. $sql = "status=99".$where." AND catid IN ($catids_str)".$thumb;   
  9. else {   
  10. $sql = "status=99".$where." AND catid='$catid'".$thumb;   
  11. }   
  12. else {   
  13. $thumb = intval($data['thumb']) ? " AND thumb != ''" : '';   
  14. if($this->category[$catid]['child']) {   
  15. $catids_str = $this->category[$catid]['arrchildid'];   
  16. $pos = strpos($catids_str,',')+1;   
  17. $catids_str = substr($catids_str, $pos);   
  18. $sql = "status=99 AND catid IN ($catids_str)".$thumb;   
  19. else {   
  20. $sql = "status=99 AND catid='$catid'".$thumb;   
  21. }   
  22. }   

其实主要的修改思路是$where参数中并不包含当前栏目的id值,所以在$sql增加获取相关id的参数


第二个问题:分页数量不对

通过研究缓存得知,调用分页总数的函数是:
  1. $content_total = $content_tag->count(array('catid'=>$catid,'where'=>$sql,'modelid'=>$modelid,'moreinfo'=>'1','limit'=>$offset.",".$pagesize,'action'=>'lists',)); 
通过这个,找到phpcmsmodulescontentclassescontent_tag.class.php大致36-56行,count函数如下:

  1. public function count($data) { 
  2.         if($data['action'] == 'lists') { 
  3.             $catid = intval($data['catid']); 
  4.             if(!$this->set_modelid($catid)) return false
  5.             if(isset($data['where'])) { 
  6.                 $sql = $data['where']; 
  7.             } else { 
  8.                 if($this->category[$catid]['child']) { 
  9.                     $catids_str = $this->category[$catid]['arrchildid']; 
  10.                     $pos = strpos($catids_str,',')+1; 
  11.                     $catids_str = substr($catids_str, $pos); 
  12.                     $sql = "status=99 AND catid IN ($catids_str)"
  13.                 } else { 
  14.                     $sql = "status=99 AND catid='$catid'"
  15.                 } 
  16.             } 
  17.             return $this->db->count($sql); 
  18.         } 
  19.     } 

改为:
  1. public function count($data) { 
  2.         if($data['action'] == 'lists') { 
  3.             $catid = intval($data['catid']); 
  4.             $catids_str = $this->category[$catid]['arrchildid']; 
  5.             if(!$this->set_modelid($catid)) return false
  6.             if(isset($data['where'])) { 
  7.                  $sql = $data['where']; 
  8.                 if($this->category[$catid]['child']) {   
  9.                 $catids_str = $this->category[$catid]['arrchildid'];   
  10.                 $pos = strpos($catids_str,',')+1;   
  11.                 $catids_str = substr($catids_str, $pos);   
  12.                 $sql = $sql." AND catid IN ($catids_str)"
  13.                 } else {   
  14.                 $sql = $sql." AND catid='$catid'"
  15.                 }   
  16.             } else { 
  17.                 if($this->category[$catid]['child']) { 
  18.                     $catids_str = $this->category[$catid]['arrchildid']; 
  19.                     $pos = strpos($catids_str,',')+1; 
  20.                     $catids_str = substr($catids_str, $pos); 
  21.                     $sql = "status=99 AND catid IN ($catids_str)"
  22.                 } else { 
  23.                     $sql = "status=99 AND catid='$catid'"
  24.                 } 
  25.             } 
  26.             return $this->db->count($sql); 
  27.         } 
  28.     } 

 


你会发现,分页统计的修改原理仍然是$where条件下,没有传入当前栏目id这个参数!


大功告成,这样既然正常分页传参,也能正常获取当前栏目信息,获取的信息总数也正确了

但是,我并没有测试在get方式下,是不是有影响,欢迎大家测试!!!

相关推荐

扫码关注

qrcode

QQ交谈

回顶部