PHP分页显示制作详细讲解


Posted in PHP onNovember 19, 2008

每页多少条记录($PageSize)?

当前是第几页($CurrentPageID)?

现在只要再给我一个结果集,我就可以显示某段特定的结果出来。

至于其他的参数,比如:上一页($PreviousPageID)、下一页($NextPageID)、总页数($numPages)等等,都可以根据前边这几个东西得到。

以mysql数据库为例,如果要从表内截取某段内容,sql语句可以用:select * from table limit offset, rows。看看下面一组sql语句,尝试一下发现其中的规率。

前10条记录:select * from table limit 0,10

第11至20条记录:select * from table limit 10,10

第21至30条记录:select * from table limit 20,10

……

这一组sql语句其实就是当$PageSize=10的时候取表内每一页数据的sql语句,我们可以总结出这样一个模板:
select * from table limit ($CurrentPageID - 1) * $PageSize, $PageSize

拿这个模板代入对应的值和上边那一组sql语句对照一下看看是不是那么回事。搞定了最重要的如何获取数据的问题以后,剩下的就仅仅是传递参数,构造合适的sql语句然后使用php从数据库内获取数据并显示了。以下我将用具体代码加以说明。

3、简单代码

请详细阅读以下代码,自己调试运行一次,最好把它修改一次,加上自己的功能,比如搜索等等。
<?php
// 建立数据库连接
$link = mysql_connect("localhost", "mysql_user", "mysql_password")

 or die("Could not connect: " . mysql_error());
// 获取当前页数
if( isset($_GET['page']) ){
  $page = intval( $_GET['page'] );
}
else{
  $page = 1;
}
// 每页数量
$PageSize = 10;
// 获取总数据量
$sql = "select count(*) as amount from table";
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$amount = $row['amount'];
// 记算总共有多少页
if( $amount ){
  if( $amount < $page_size ){ $page_count = 1; }

  //如果总数据量小于$PageSize,那么只有一页
  if( $amount % $page_size ){

 //取总数据量除以每页数的余数

  $page_count = (int)($amount / $page_size) + 1;

  //如果有余数,则页数等于总数据量除以每页数的结果取整再加一
  }else{

  $page_count = $amount / $page_size;

 //如果没有余数,则页数等于总数据量除以每页数的结果
  }
}
else{
  $page_count = 0;
}
// 翻页链接
$page_string = '';
if( $page == 1 ){
  $page_string .= '第一页|上一页|';
}
else{
  $page_string .= '<a href=?page=1>第一页</a>|<a href=?page='.($page-1).'>上一页</a>|';
}
if( ($page == $page_count) || ($page_count == 0) ){
  $page_string .= '下一页|尾页';
}
else{
  $page_string .= '<a href=?page='.($page+1).'>下一页</a>|<a href=?page='.$page_count.'>尾页</a>';
}
// 获取数据,以二维数组格式返回结果
if( $amount ){
  $sql = "select * from table order by id desc limit ". ($page-1)*$page_size .", $page_size";
  $result = mysql_query($sql);
 
  while ( $row = mysql_fetch_row($result) ){

  $rowset[] = $row;
  }
}else{
  $rowset = array();
}
// 没有包含显示结果的代码,那不在讨论范围,只要用foreach就可以很简单的用得到的二维数组来显示结果
?>

4、OO风格代码

以下代码中的数据库连接是使用的pear db类进行处理
<?php
// FileName: Pager.class.php
// 分页类,这个类仅仅用于处理数据结构,不负责处理显示的工作
Class Pager
{
  var $PageSize;

//每页的数量
  var $CurrentPageID;

//当前的页数
  var $NextPageID;

  //下一页
  var $PreviousPageID;

  //上一页
  var $numPages;

//总页数
  var $numItems;

//总记录数
  var $isFirstPage;

 //是否第一页
  var $isLastPage;

  //是否最后一页
  var $sql;

 //sql查询语句
 
 function Pager($option)
  {

  global $db;

  $this->_setOptions($option);

  // 总条数

  if ( !isset($this->numItems) )

  {

  $res = $db->query($this->sql);

  $this->numItems = $res->numRows();

  }

  // 总页数

  if ( $this->numItems > 0 )

  {

  if ( $this->numItems < $this->PageSize ){ $this->numPages = 1; }

  if ( $this->numItems % $this->PageSize )

  {

  $this->numPages= (int)($this->numItems / $this->PageSize) + 1;

  }

  else

  {

  $this->numPages = $this->numItems / $this->PageSize;

  }

  }

  else

  {

  $this->numPages = 0;

  }

 

  switch ( $this->CurrentPageID )

  {

  case $this->numPages == 1:

  $this->isFirstPage = true;

  $this->isLastPage = true;

  break;

  case 1:

  $this->isFirstPage = true;

  $this->isLastPage = false;

  break;

  case $this->numPages:

  $this->isFirstPage = false;

  $this->isLastPage = true;

  break;

  default:

  $this->isFirstPage = false;

  $this->isLastPage = false;

  }

 

  if ( $this->numPages > 1 )

  {

  if ( !$this->isLastPage ) { $this->NextPageID = $this->CurrentPageID + 1; }

  if ( !$this->isFirstPage ) { $this->PreviousPageID = $this->CurrentPageID - 1; }

  }

 

  return true;
  }
 
  /***

*

* 返回结果集的数据库连接

* 在结果集比较大的时候可以直接使用这个方法获得数据库连接,然后在类之外遍历,这样开销较小

* 如果结果集不是很大,可以直接使用getPageData的方式获取二维数组格式的结果

* getPageData方法也是调用本方法来获取结果的

*

***/
 
  function getDataLink()
  {

  if ( $this->numItems )

  {

  global $db;

 

  $PageID = $this->CurrentPageID;

 

  $from = ($PageID - 1)*$this->PageSize;

  $count = $this->PageSize;

  $link = $db->limitQuery($this->sql, $from, $count);  //使用Pear DB::limitQuery方法保证数据库兼容性

 

  return $link;

  }

  else

  {

  return false;

  }
  }
 
  /***

*

* 以二维数组的格式返回结果集

*

***/
 
  function getPageData()
  {

  if ( $this->numItems )

  {

  if ( $res = $this->getDataLink() )

  {

 

  if ( $res->numRows() )

  {

  while ( $row = $res->fetchRow() )

  {

  $result[] = $row;

  }

  }

  else

  {

  $result = array();

  }

 

  return $result;

  }

  else

  {

  return false;

  }

  }

  else

  {

  return false;

  }
  }
 
  function _setOptions($option)
  {

  $allow_options = array(

  'PageSize',

  'CurrentPageID',

  'sql',

  'numItems'

  );

 

  foreach ( $option as $key => $value )

  {

  if ( in_array($key, $allow_options) && ($value != null) )

  {

  $this->$key = $value;

  }

  }

 

  return true;
  }
}
?>
<?php
// FileName: test_pager.php
// 这是一段简单的示例代码,前边省略了使用pear db类建立数据库连接的代码
require "Pager.class.php";
if ( isset($_GET['page']) )
{
  $page = (int)$_GET['page'];
}
else
{
  $page = 1;
}
$sql = "select * from table order by id";
$pager_option = array(

  "sql" => $sql,

  "PageSize" => 10,

  "CurrentPageID" => $page
);
if ( isset($_GET['numItems']) )
{
  $pager_option['numItems'] = (int)$_GET['numItems'];
}
$pager = @new Pager($pager_option);
$data = $pager->getPageData();
if ( $pager->isFirstPage )
{
  $turnover = "首页|上一页|";
}
else
{
  $turnover = "<a href='?page=1&numItems=".$pager->numItems."'>首页</a>|<a href='?page=".$pager->PreviousPageID."&numItems=".$pager->numItems."'>上一页</a>|";
}
if ( $pager->isLastPage )
{
  $turnover .= "下一页|尾页";
}
else
{
  $turnover .= "<a href='?page=".$pager->NextPageID."&numItems=".$pager->numItems."'>下一页</a>|<a href='?page=".$pager->numPages."&numItems=".$pager->numItems."'>尾页</a>";
}
?>

需要说明的地方有两个:

这个类仅仅处理数据,并不负责处理显示,因为我觉得将数据的处理和结果的显示都放到一个类里边实在是有些勉强。显示的时候情况和要求多变,不如自己根据类给出的结果处理,更好的方法是根据这个Pager类继承一个自己的子类来显示不同的分页,比如显示用户分页列表可以:
<?php
Class MemberPager extends Pager
{
  function showMemberList()
  {

  global $db;

 

  $data = $this->getPageData();
// 显示结果的代码

  // ......
  }
}
/// 调用
if ( isset($_GET['page']) )
{
  $page = (int)$_GET['page'];
}
else
{
  $page = 1;
}
$sql = "select * from members order by id";
$pager_option = array(

  "sql" => $sql,

  "PageSize" => 10,

  "CurrentPageID" => $page
);
if ( isset($_GET['numItems']) )
{
  $pager_option['numItems'] = (int)$_GET['numItems'];
}
$pager = @new MemberPager($pager_option);
$pager->showMemberList();
?>

第二个需要说明的地方就是不同数据库的兼容性,在不同的数据库里截获一段结果的写法是不一样的。
mysql: select * from table limit offset, rows
pgsql: select * from table limit m offset n
......

所以要在类里边获取结果的时候需要使用pear db类的limitQuery方法。

ok,写完收功,希望花时间看完这些文字的你不觉得是浪费了时间。

PHP 相关文章推荐
分页详解 从此分页无忧(PHP+mysql)
Nov 23 PHP
php表单转换textarea换行符的方法
Sep 10 PHP
PHP FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)
Jul 23 PHP
php上传图片之时间戳命名(保存路径)
Aug 15 PHP
PHP中使用asort进行中文排序失效的问题处理
Aug 18 PHP
Docker 如何布置PHP开发环境
Jun 21 PHP
Yii框架分页实现方法详解
May 20 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
Jun 09 PHP
利用Homestead快速运行一个Laravel项目的方法详解
Nov 14 PHP
PHP常见加密函数用法示例【crypt与md5】
Jan 27 PHP
Laravel 框架路由原理与路由访问实例分析
Apr 14 PHP
PHP8.0新功能之Match表达式的使用
Jul 19 PHP
php在字符串中查找另一个字符串
Nov 19 #PHP
IIS php环境配置PHP5 MySQL5 ZendOptimizer phpmyadmin安装与配置
Nov 18 #PHP
Linux下 php5 MySQL5 Apache2 phpMyAdmin ZendOptimizer安装与配置[图文]
Nov 18 #PHP
php 遍历显示文件夹下所有目录、所有文件的函数,没有分页的代码
Nov 14 #PHP
利用discuz实现PHP大文件上传应用实例代码
Nov 14 #PHP
php下载远程文件类(支持断点续传)
Nov 14 #PHP
PHP ajax 分页类代码
Nov 13 #PHP
You might like
PHP5.3新特性小结
2016/02/14 PHP
PHP实现小偷程序实例
2016/10/31 PHP
PHP  Yii清理缓存的实现方法
2016/11/10 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
javascript 对象定义方法 简单易学
2009/03/22 Javascript
javascript动态添加表格数据行(ASP后台数据库保存例子)
2010/05/08 Javascript
javascript动态加载实现方法一
2012/08/22 Javascript
JavaScript Math.ceil() 函数使用介绍
2013/12/11 Javascript
详谈JavaScript 匿名函数及闭包
2014/11/14 Javascript
删除Javascript Object中间的key
2014/11/18 Javascript
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
js+css实现文字散开重组动画特效代码分享
2015/08/21 Javascript
Jquery中request和request.form和request.querystring的区别
2015/11/26 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
2016/04/06 Javascript
AngularJS压缩JS技巧分析
2016/11/08 Javascript
JS限定手机版中图片大小随分辨率自动调整的方法
2016/12/05 Javascript
简单实现jQuery上传图片显示预览功能
2020/06/29 jQuery
MUI顶部选项卡的用法(tab-top-webview-main)详解
2017/10/08 Javascript
layui中layer前端组件实现图片显示功能的方法分析
2017/10/13 Javascript
浅谈React和Redux的连接react-redux
2017/12/04 Javascript
Vue.js 十五分钟入门图文教程
2018/09/12 Javascript
JS实现炫酷雪花飘落效果
2020/08/19 Javascript
Python入门篇之数字
2014/10/20 Python
在Linux下使用Python的matplotlib绘制数据图的教程
2015/06/11 Python
python使用Paramiko模块实现远程文件拷贝
2019/04/30 Python
pandas read_excel()和to_excel()函数解析
2019/09/19 Python
python实现WebSocket服务端过程解析
2019/10/18 Python
python list多级排序知识点总结
2019/10/23 Python
Avène雅漾美国官方网站:敏感肌肤护理专家
2016/10/24 全球购物
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
应届生求职信写作技巧
2013/10/24 职场文书
《三峡》教学反思
2014/03/01 职场文书
群众路线自查自纠工作情况报告
2014/10/28 职场文书
庭外和解协议书
2016/03/23 职场文书
使用RedisTemplat实现简单的分布式锁
2021/11/20 Redis
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android