欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

ThinkPHP3.1快速入门(18)数据分页

shiping1 的头像
我们已经了解了如何进行数据查询,今天我们来学习下如何对数据进行分页以及显示。

获取分页类

ThinkPHP提供了数据分页的扩展类库Page,可以在http://www.thinkphp.cn/extend/241.html下载,或者下载官方的完整扩展包(http://www.thinkphp.cn/down/253.html)里面也已经包含分页扩展类了。把解压后的Page.class.php放入ThinkPHP/Extend/Library/ORG/Util/(如果没有请手动创建)目录下面。
当然,扩展类库的位置其实比较随意,你也可以放入项目的类库目录下面,区别只是在于你导入路径的不同而已。

分页查询

分页类需要和查询相结合,我们可以使用ThinkPHP自带的limit方法或者page方法,目的就是为了获取当前分页的数据(也有先获取完整数据然后前端分页显示的方法,不在本文描述内容中,也不建议)。使用limit方法或者page方法是和数据库类型无关的。
我们首先在数据库里面创建一个think_data数据表用于测试:
  1.     CREATE TABLE IF NOT EXISTS `think_data` (
  2.       `id` smallint(4) unsigned NOT NULL AUTO_INCREMENT,
  3.       `title` varchar(255) NOT NULL,
  4.       `content` varchar(255) NOT NULL,
  5.       `create_time` int(11) unsigned NOT NULL,
  6.       PRIMARY KEY (`id`)
  7.     ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;
复制代码
 
要使用分页查询,一般来说需要进行两次查询,即第一次查询得到满足条件的总数据量,然后第二次查询当前分页的数据,这样做的作用是告诉分页类当前的数据总数,以便计算生成的总页数(如果你的显示只是需要上下翻页的话,其实总数查询可以省略或者进行缓存)。
一个标准的分页使用示例如下:
  1.     $Data = M('Data'); // 实例化Data数据对象
  2.     import('ORG.Util.Page');// 导入分页类
  3.     $count      = $Data->where($map)->count();// 查询满足要求的总记录数 $map表示查询条件
  4.     $Page       = new Page($count);// 实例化分页类 传入总记录数
  5.     $show       = $Page->show();// 分页显示输出
  6.     // 进行分页数据查询
  7.     $list = $Data->where($map)->order('create_time')->limit($Page->firstRow.','.$Page->listRows)->select();
  8.     $this->assign('list',$list);// 赋值数据集
  9.     $this->assign('page',$show);// 赋值分页输出
  10.     $this->display(); // 输出模板
复制代码
 
如果没有任何数据的话,分页显示为空白。所以在进行测试之前,请确保你的数据表里面有一定的数据,否则可能看不到分页的效果。如果使用page方法查询的话,则可以改成:
  1.     $Data = M('Data'); // 实例化Data数据对象
  2.     import('ORG.Util.Page');// 导入分页类
  3.     $count      = $Data->where($map)->count();// 查询满足要求的总记录数
  4.     $Page       = new Page($count);// 实例化分页类 传入总记录数
  5.     // 进行分页数据查询 注意page方法的参数的前面部分是当前的页数使用 $_GET[p]获取
  6.     $nowPage = isset($_GET['p'])?$_GET['p']:1;
  7.     $list = $Data->where($map)->order('create_time')->page($nowPage.','.$Page->listRows)->select();
  8.     $show       = $Page->show();// 分页显示输出
  9.     $this->assign('page',$show);// 赋值分页输出
  10.     $this->assign('list',$list);// 赋值数据集
  11.     $this->display(); // 输出模板
复制代码
 
然后,我们在模板中添加分页输出变量即可:
  1. <table cellpadding=3 cellspacing=5>
  2.  <volist name="list" id="vo">
  3.  <tr>
  4.  <td >[ {$vo.create_time|date='Y-m-d H:i:s',###} ] {$vo.title} </td>
  5.  </tr>
  6.  </volist>
  7.  <tr>        
  8.  </tr>
  9.  </table>
  10.  <div class="result page">{$page}</div>
复制代码
 
可以看到分页输出只需要采用{$page}变量在模板中输出即可。

分页设置

设置分页变量

默认情况下,分页传值的变量是p,生成的分页跳转地址可能类似于:
  1. http://serverName/index.php/Data/index/p/1
  2. http://serverName/index.php/Data/index/p/2
复制代码
 
我们可以配置VAR_PAGE配置参数来改变:
  1. 'VAR_PAGE'=>'page'
复制代码
 
则分页地址变成:
  1. http://serverName/index.php/Data/index/page/1
  2. http://serverName/index.php/Data/index/page/1
复制代码
 

设置每页记录数

默认的情况下,分页显示每页会显示20条数据,如果你希望改变每页显示的数据量的话,实例化分页类的时候可以传人第二个参数即可:
  1. $Page       = new Page($count,5);// 实例化分页类 传入总记录数并且每页显示5条记录
复制代码
 
由于查询方法中我们使用了$Page->listRows属性,所以无需更改,但如果你是直接在查询方法中使用数字请记得一起更改。
下面是官方的分页示例的显示效果:

传入分页条件

默认情况下,分页类会自动获取当前页面的POST(优先)或者GET变量作为分页跳转的传值,如果需要指定传入当前分页跳转的参数,就可以通过设置parameter属性,parameter属性支持2种方式传值:字符串和数组。字符串采用var1=val1&var2=val2...的格式,例如:
  1. foreach($map as $key=>$val) {
  2.     $Page->parameter   .=   "$key=".urlencode($val).'&';
  3.  }
复制代码
 
或者直接传入数组:
  1. $Page->parameter   =   array_map('urlencode',$map);
复制代码
 
由于内部调用了U函数,分页类最终生成的分页跳转链接会根据当前的URL设置自动生成和当前URL模式一致的地址,所以无需担心分页链接的参数影响URL地址。

分页路由支持

如果你的分页跳转链接地址采用了路由,那么可以通过设置url参数,例如,假设我们的分页URL地址格式是:
  1. http://serverName/data/index/1
  2. http://serverName/data/index/2
  3. http://serverName/data/index/3
复制代码
 
这样的URL路由地址,那么我们就可以设置
  1. $Page->url = 'data/index';
复制代码
 
设置后,分页类的链接地址会自动生成上面的URL格式地址。
注意,url参数和parameter 同时使用的话,后者无效。

设置显示的页数

可以在实例化分页类之后,进行相关属性的设置。默认情况下,页面显示的页数是5,我们可以修改:
  1. $Page->rollPage = 3;
复制代码
 
这样,页面上只能同时看到3个分页

分页显示定制

上面讲的是分页的参数设置,下面讲下如何对分页显示效果(包括样式)进行设置。默认的分页效果可能不能满足所有的要求,分页类提供了一个setConfig方法来修改默认的一些设置。例如:
  1. $page->setConfig('header','个会员');
复制代码
 
setConfig方法支持的属性包括:
header头部描述信息,默认值 “条记录”
prev上一页描述信息,默认值是“上一页”
next下一页描述信息,默认值是“下一页”
first第一页描述信息,默认值是“第一页”
last最后一页描述信息,默认值是“最后一页”
theme分页主题描述信息,包括了上面所有元素的组合 ,设置该属性可以改变分页的各个单元的显示位置,默认值是
"%totalRow% %header% %nowPage%/%totalPage% 页 %upPage% %downPage% %first% %prePage% %linkPage% %nextPage% %end%"
通过setConfig设置以上属性可以完美的定制出你的分页显示风格。
评论(53相关
ssytg02月22日
为什么点击第2页或者下一页不显示
IT牛人10月29日
学了之后有什么技术问题,可以到<<thinkphp群>> 去请教, 有专门老师免费辅导 
群号 364702379
左西10月06日
不错
hgaoping04月20日
分页的不支持123....90这样子的格式,功能还是。。。的自己扩展吧
hgaoping04月20日
给个小建议啊,把 C('VAR_PAGE') && $this->p = C('VAR_PAGE'); 写死的方式改成可以动态传参数的方式,要不然,一个页面里面不能支持多个分页。
sujiexiao2015年02月28日
可以用AJAX吗?总觉得用跳转分页很麻烦呐~
lsmir22015年01月19日
  1.  
  2. $Model= M();
  3. $res=$Model->query("select UserID from TUsers");
  4.  
复制代码
复制代码
复制代码
 
复制代码
 
复制代码
 
复制代码
 
复制代码
 

我直接使用Query 如何使用分页类呢?,因为 sql语句有点复杂.用 $Model->select有点麻烦
cnznzm2015年01月02日
PHP Fatal error: Class 'Admin\Controller\Page' not found in 什么原因 我用的3.2.3完整版 那个page.class.php还有安装吗,装的话放在哪
回复thinkphp2015年01月03日
命名空间使用错误
回复hanenci07月14日
回复 hanenci : 123
swk1802014年12月07日
太多页面,我想在中间显示省略号怎么办??
首页 上一页 1 2 3 4 5 …… 9 10 下一页 末页
51xni2014年11月21日
没人遇到过需要缓存并且需要分页的问题吗??
rgbhje2014年11月21日
我在index.php里做的,点下一页和1234页码,url地址越来越长,每点一次增加点东西,界面数据也不翻页,http://127.0.0.1/webapp/index.php/Index/index/0/2/1/2/2/2/3/2/4/2/5/2/6/2/7/2/8/4/9/4/10/1.html
shorlyn2014年11月15日
3.2的怎么修改让首页,尾页,上一页,下一页一直显示?
px920002014年11月03日
page.class.php修改
注释 //$this->lastSuffix && $this->config['last'] = $this->totalPages; //此处会导致end标签的样式定义失效
改为 $this->lastSuffix = $this->totalPages;
控制器:
...
$Page = new \Think\Page($count, 1);
...
$Page->setConfig('prev', "上一页");//上一页
$Page->setConfig('next', '下一页');//下一页
$Page->setConfig('first', '首页');//第一页
$Page->setConfig('last', "末页");//最后一页
$Page -> setConfig ( 'theme', '%HEADER% %FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%' );
...
$this -> assign("page", $show);
$this -> display();
效果
共 12 条记录 首页 上一页 23456789101112 下一页 末页
回复且试天下201205月06日
非常好
回复草原狼209月23日
回复 且试天下2012 : 怎么把下一页显示在右边的?求教 1309265274@qq.com
quan1232014年10月25日
dnfsnf jndkjsfd ds fsdf sdf
jobs2014年10月10日
像本留言板这种点击查看,然后就展开内容的方式是怎么实现的啊?
smallfish2014年08月18日
急切求助:为什么查询的结果分页只能看到第一页的内容,点第二页的时候就自动跳到查询之前的全部记录页面了,求大神贴个代码出来
stcg0012014年06月14日
我需要 一个 像这样显示的分页 :
首页 上一页 1 2 3 4 5 6 7 8 9 10 下一页 末页
不知道哪位大神给我个解决的办法。
回复stcg0012014年06月14日
我说的是无论什么时候 都保持 
首页 上一页 1 2 3 4 5 6 7 8 9 10 下一页 末页
这个样子 ,不管是第一页 ,还是最后一页。
回复kais7mg2014年09月17日
回复 stcg001 : $page->setConfig('theme','格式');
huangma2014年04月23日
  1. sdadsad
复制代码
 
复制代码
 
复制代码
 
复制代码
 
复制代码
 
回复hanenci07月14日
$Page = new Page($count,5);// 实例化分页类 传入总记录数并且每页显示5条记录
cx3432014年03月10日
原来不显示第一页和最后一页是因为页数不够多 大于5页就可以显示了
回复buddyli2014年04月21日
回复 buddyli : 22222222222222222
akjaskjdfalkdjh
回复buddyli2014年04月21日
PHP3.1快速入门(18)数据分页
ThinkPHP3.1快速入门(19)文件上传
ThinkPHP3.1快速入门(20)验证码
ThinkPHP3.1快速入门(21)IP地址定位
ThinkPHP3.1快速入门(22)行为
回复quan1232014年10月25日
回复 buddyli :
cx3432014年03月10日
为什么不显示 首页和最后页
hulanker2013年12月20日
NB
LUN2013年12月03日
学习了
tree1002013年11月22日
很好的说呢
daley2013年10月15日
能出个支持Ajax的分页吗?
yj2438939422013年10月10日
感觉只能出现列表显示的效果,如果想在list中添加判断不久不行了吗
XoUI2013年09月22日
应该是 $Page->setConfig('header','个会员');
qmit2013年09月02日
url参数和parameter 同时使用的话,后者无效。
=============================
那如果我想要下面的URL:
http://serverName/data/index/3?type=news&tag=1
那该如何才行得通啊?
回复jiewuzhe022013年11月16日
哎,,,,
回复kais7mg2014年09月17日
回复 jiewuzhe02 : $Page->url = 'Index/index/type/news/tag/1/page';
5646431222013年08月29日
東西都可以保留的
dypcsx2013年08月16日
分页有没有类似于line id的东西,我想做单双行颜色不同。还有就是想把置顶的放在第一页,第一页包含置顶+普通数据,2,3,4,5之后,每页数据数量一致,
zzbszsw2013年08月12日
这样的分页结构,分页的效果是实现了,但是对于seo没有什么好处吧
fj_dong2013年08月11日
为什么 首页 最后一页 都出不来
回复hmildd2013年08月28日
是因为你的分页不够多
回复♞崔苔吾2013年11月28日
回复 hmildd :
petbug2013年08月10日
好好学习了。真的还不会分类。丢人啊。
xazzz2013年07月31日
尝试了,没成功
petbug2013年07月30日
还不会分页,要好好学习了。。。
jm19662013年07月06日
分页后想在打印机上打印,调用什么?
785480779@qq.com2013年06月03日
网站URL带html伪静态,用了分页路由之后,为什么不带html了
http://127.0.0.1/Lists/18.html
http://127.0.0.1/lists/18/p/2
回复max4ever2013年06月27日
自己修改下page函数库吧,先用C函数读取伪静态后缀,然后在相应的地方加上就好了~
回复jiayouzl2014年07月02日
回复 max4ever : 擦我也碰到这个问题!
回复lijieyahoo12月12日
回复 jiayouzl : 同求
785480779@qq.com2013年06月03日
网站URL带html伪静态,用了分页路由之后,为什么不带html了
et06622013年04月25日
项目分组啦,结果生成的上一页,下一页这些连接不对~
第二页来说本来应该是:
http://localhost/index.php/Admin/Brand/index/p/2
结果变成了
http://localhost/index.php/Brand/index/p/2
肿么办?
回复et06622013年04月28日
用新版本的分页插件~
lz198811232013年04月23日
'page/:p\d'=>'Index/index', //首页文章列表分页 我这样设置,但是分页的时候还是出现:
http://127.0.0.1/index/index/page/2.html
cffall2013年04月07日
parameter属性不支持
  1. $map['id']  = array('not in',array('1','5','8'));
复制代码
 
复制代码
 
复制代码
 
这样的参数吗?
不是那样子的
$page->parameter.="&参数名=".参数值;
所以数组$map[参数名]='参数对应的值';
桃李2013年03月20日
按照上面的要求去测试。page能出来,可是list数据空的?这是为什么?
回复clearly2013年07月21日
我是每页查询出来的结果都一样。
z199006192013年03月13日
关于下几页的翻页,现在设置的是直接从当前页加几,这就导致有时候跳转的页数比查询的页数多,而跳转的页面却没有数据,希望改成如果页数不足的情况下跳转到最后一页就好了
2的1024次方2013年03月08日
19 条记录 1/5 页 下一页 1 2 3 有这些,为什么没有首页 和 尾页 呀?我按照官网教程做的.
thinkphpadmin2013年02月23日
$page->setConfig('header','会员');
$page->setConfig('prefv','上一组会员');
$page->setConfig('next','下一组会员');
$page->setconfig('first','首页');
$page->setconfig('last','尾页');
$page->setConfig('theme','<div style="font-weight:bold;">总共:%totalRow%%header% %nowPage%/%totalPage%页 %first% %upPage% %prePage% %linkPage% %nextPage% %downPage% %end%</div>');
报错啊:Fatal error: Call to a member function setConfig() on a non-object in D:\WorkSpace\xiaohongniang\apps\home\Lib\Action\PublicAction.class.php on line 18
回复jieyao2013年09月12日
$Page 首字母要大写,官方粗心了。
anseldu2013年02月14日
'URL_ROUTE_RULES' => array( 
'/^place\/c(\d+)\/(\d+)$/' => 'Place/comments?ctype=:1&idx=:2', //形如: /place-c1-33.html
),
回复anseldu2013年02月14日
正常情况下,分页没有一点问题,但是如果路由如果设置成正则的时候就会出问题,比如如上的配置,
当前页:.../place-c1-33.html
换第二页时系统自动搞成了 .../place-33-p-2.html ,硬生生把 "-c1-"给去掉了。
有没有什么办法解决?
回复lxsszwhh2014年07月24日
回复 anseldu :
红酒独醉2013年02月02日
当前页,怎么设置显示效果
machao5162013年01月16日
Bug报告,下5页的链接,是直接在当前页数上加5,这样会出问题。比如我有7页的数据,当前在第4页,点下5页,直接到了第9页
回复dafa1682013年02月04日
同样的BUG 也出现了 出现的地是: User/index/0/1/2/2/3/5/2 点击5次才能跳转到下一页 肯定是URL上面出现问题了,以前没有这个参数的
kxy0002012年12月27日
额。。如何去掉分页URL中的index 呢
回复icaigen.com2012年12月28日
模块方法中:
  1.  
  2.  ...
  3. $Page->url = 'page';
  4. $nowPage = isset($_GET['p']) ? $_GET['p'] : 1;
  5.  ...
  6.  
复制代码
 
复制代码
 

config.php中
  1.  
  2.  'URL_ROUTE_RULES'=>array(
  3.         'page/:p\d'=>'Index/index', //首页文章列表分页
  4.     ),
  5.  
复制代码
 
复制代码
 
周小渊212012年12月12日
ajax分页 对于页面处理 感觉不够
回复thinkphp2012年12月12日
可以参考ajax分页示例:http://www.thinkphp.cn/extend/246.html
深深的呼吸1232012年12月11日
如果我传的post的name为“game”的话,$game=$_POST['kf_keyword'],那么$Page->parameter = array_map('urlencode',$map);这个 应改成什么?谢谢!!
深深的呼吸1232012年12月11日
能不能详细讲一下用post传参的情况!!
回复thinkphp2012年12月12日
post传参默认就支持,只有需要对参数进行过滤或者处理的时候才需要单独设置parameter参数
hsishows2012年12月11日
能否开发一个js的模板引擎,虽然现在是可以很简单实现ajax无刷新的功能,但是模板中的html标签和数据,都是从后端解析和返回过来的,这样请求的返回的文件会相对较大,如果列表比较多,模板的dom元素比较多的话,就更加明显了,我想把模板放在前端解析,然后显示,ajax只调用json数据。
回复hsishows2012年12月12日
我的问题,不能回答一下吗?如果开发一个js模板引擎会非常困难,那有没有办法可以把thinkphp现有的模板引擎$content=$this->fetch('')放到模板中使用呢?这样就可以实现ajax只拿json数据,拿回来之后再通过渲染模板再显示到页面上.html($content)
回复xiaobaijing2013年01月12日
这个问题我也在想解决办法,现在我认为比较可行的方法就是自己写一个js模板类,利用Thinkphp的Widegt类,利用模板替换和正则的方式把Widegt类转换成js函数,然后输出到页面。。。
在使用的时候,利用ajax调用js函数就可以了。。。。。
王少雄2012年12月08日
$page->setConfig('header','个会员'); 如何定义成多语言?
回复thinkphp2012年12月09日
  1. $page->setConfig('header',L('header'));
复制代码
 
header为你定义的语言变量
回复xiaochong03022012年12月27日
这种方式来定于多语言不要蛋疼死阿,多个页面有分页还要定义多次,支持应该在Page类内部支持多语言,外部只要给相应的变量定于语言包就可以了。
回复疯语者2013年09月10日
回复 xiaochong0302 : %downPage%

普通分类: