数据一般有许多分类项,好比12306买车票时,能够选择哪一种类型的车次,开车时间段,始发地等条件。最近在作一个线上考试系统,为了方便试题管理,也提供了分类筛选功能,下面简单说一下用原生PHP实现的方法。javascript
首先,页面效果图以下:php
分类项主要有2个:一个是根据题库分,一个是根据题型分(基础题,编程题等)。还有一个,不算是分类项,但也算是筛选数据的一个信息,就是左下角每页显示的条数。java
咱们先来分析下实现原理:无论前面怎么筛选,最终进行数据查找的Sql语句都是这样的:sql
SELECT * FROM 表名 WHERE ...
因此,咱们的重点就是获取WHERE后面的筛选条件。编程
怎么获取呢?当咱们选中下拉框时,下拉框中的值传入后台服务器处理无非2种方式,一是经过表单POST传递,二是经过URL中添加参数GET传递。(不考虑Ajax方式)。这里,因为不存在安全性问题(即传递的数据不是用户名、密码等敏感信息),因此,进行数据筛选通常都是经过URL添加参数的GET方式传递信息。安全
肯定了数据传递方式后,咱们就要实现传递数据。这里,咱们假设未进行数据筛选时的页面网址为:www.question.com。无论咱们选中下拉的哪个,都会在该URL中添加参数,而后从新刷新页面。假设题库、题型还有显示条数这3个下拉框select的name属性分别是category、type、nums,咱们为每一个select绑定change事件:服务器
<script> $('select').on('change',function(){ var url = "www.question.com?"; var category = '&category='+$("[name='category']").val(); var type = '&type='+$("[name='type']").val(); var nums = '&nums='+$("[name='nums']").val(); url += category + type +nums; $('form').attr('action',url).submit(); }) </script>
解释:任何一个select的值发生变化,都将全部当前select的值做为参数加入到www.question.com中,并经过表单元素form元素提交(实际是就是刷新本页面),这样就把全部筛选条件都传递过去了。url
下面就是获取传递条件,进行数据筛选。spa
注意,题库和题型中都有所有这个选项,其对应的value值是'all',显然,all是不具备筛选项的。WHERE子句的格式为:code
WHERE 字段=值 AND 字段=值 AND 字段=值
显然,若是题库是所有,咱们就不能有第一个字段,那题型前面就不能有AND;但是题型也不肯定是否为所有,所以第三个字段前面要不要加AND也不肯定。简单的说,就是下一个字段前是否有AND取决于它前面是否有字段,第二个字段须要考虑第一个字段是否存在,第三个字段须要考虑前2个字段是否存在,这种级联关系十分复杂,根本不能经过if else来判断。
该怎么解决呢?咱们只须要将字段独当即可,即每一个字段的AND不须要考虑其余字段是否存在。先看代码:
<?php $condition = " 'ack'='ack'";//注意,前面有个空格 if(isset($_GET['category'])){ if($_GET['category']!='all') $condition.=" AND category='".$_GET['category']."'"; } //其它筛选项相似,只须要将category换成type和nums便可 ?>
将WHERE后面的筛选条件建立一个变量$condition。默认值是‘ack’='ack'。这什么意思呢?其实,sql进行筛选信息时,是进行真假判断,字符串'ack'='ack'显然为真,因此至关于没有添加筛选条件,ack能够换成任何值,固然,也能够写成1=1,0=0,只要为真就行。
加入这个条件是为了后面字段方便。这样,只要后面字段存在,它前面就必定要加AND,由于ack做为第一个字段。这样就不要考虑是否要加AND的问题了。
而后将$condition加入到WHERE子句中便可:
'SELECT * FROM 表名 WHERE'.$condition
能够看出,WHERE后紧跟$condition,这就是为何'ack'前要有空格的缘由了。
很简单吧?总结下数据筛选:
经过GET方式将全部筛选信息进行拼接后传递——根据传递来的数据建立$condition——进行数据筛选,这里惟一的小技巧就是ack。
至于分页:相似于筛选条件,只不过它不是建立WHERE子句,而是建立LIMIT子句。这里,咱们只考虑最简单的状况,即:
首页 上一页 下一页 尾页
这种连接形式。
咱们在翻页时,是在当前筛选条件下完成的,所以,须要保留筛选信息。因为连接形式和where查询类似:
www.question.com?参数=值&参数=值&参数=值
采用相同ack处理方法,建立一个查询字符串的变量,将上面的PHP语句添加内容为:
<?php $condition = " 'ack'='ack'";//注意,前面有个空格 $query_str = "ack=ack";//查询字符串,注意,这里ack就不要加引号了 if(isset($_GET['category'])){ if($_GET['category']!='all') $condition.=" AND category='".$_GET['category']."'"; $query_str.= $_GET['category']; } //其它筛选项相似,只须要将category换成type和nums便可 ?>
这样,就保留住了筛选条件了。而后输出分页连接:
if(当前不是第一页){ $link = '<a href="首页连接">首页</a><a href="上一页连接">上一页</a>'; } else{ $link = '<button>首页</button><button>上一页</button>' } if(不是最后一页){ $link .= '<a href="下一页连接">下一页</a><a href="尾页连接">尾页</a>'; } else{ $link .= '<button>下一页</button><button>尾页</button>' }
不是第一页,则前面必定有页数,因此建立为连接a形式,反正是不能连接的button
形式。同理,不是最后一页,则后面必定有页数,建立为连接形式,反之button形式。其中,连接中的href就拼接的结果,好比首页连接:
'www.question.com?'.$query_str.'&page=1'