PHP应用分页显示制作详细讲解
1、前言
分页显示是一种非常常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之一。对于web编程的老手来说,编写这种代码实在是和呼吸一样自然,但是对于初学者来说,常常对这个问题摸不着头绪,因此特地撰写此文对这个问题进行详细的讲解,力求让看完这篇文章的朋友在看完以后对于分页显示的原理和实现方法有所了解。本文适合初学者阅读,所有示例代码均使用php编写。
2、原理
所谓分页显示,也就是将数据库中的结果集人为的分成一段一段的来显示,这里需要两个初始的参数:
每页多少条记录($PageSize)?
当前是第几页($CurrentPageID)?
现在只要再给我一个结果集,我就可以显示某段特定的结果出来。
至于其他的参数,比如:上一页($PreviousPageID)、下一页($NextPageID)、总页数($numPages)等等,都可以根据前边这几个东西得到。
以mysql数据库为例,如果要从表内截取某段内容,sql语句可以用:select*fromtablelimitoffset,rows。看看下面一组sql语句,尝试一下发现其中的规率。
前10条记录:select*fromtablelimit0,10
第11至20条记录:select*fromtablelimit10,10
第21至30条记录:select*fromtablelimit20,10
……
这一组sql语句其实就是当$PageSize=10的时候取表内每一页数据的sql语句,我们可以总结出这样一个模板:
select*fromtablelimit($CurrentPageID-1)*$PageSize,$PageSize
拿这个模板代入对应的值和上边那一组sql语句对照一下看看是不是那么回事。搞定了最重要的如何获取数据的问题以后,剩下的就仅仅是传递参数,构造合适的sql语句然后使用php从数据库内获取数据并显示了。以下我将用具体代码加以说明。
3、简单代码
请详细阅读以下代码,自己调试运行一次,最好把它修改一次,加上自己的功能,比如搜索等等。
<?php
//建立数据库连接
$link=mysql_connect("localhost","mysql_user","mysql_password")
ordie("Couldnotconnect:".mysql_error());
//获取当前页数
if(isset($_GET["page"])){
$page=intval($_GET["page"]);
}
else{
$page=1;
}
//每页数量
$PageSize=10;
//获取总数据量
$sql="selectcount(*)asamountfromtable";
$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.="<ahref=?page=1>第一页</a>|<ahref=?page=".($page-1).">上一页</a>|";
}
if(($page==$page_count)||($page_count==0)){
$page_string.="下一页|尾页";
}
else{
$page_string.="<ahref=?page=".($page+1).">下一页</a>|<ahref=?page=".$page_count.">尾页</a>";
}
//获取数据,以二维数组格式返回结果
if($amount){
$sql="select*fromtableorderbyiddesclimit".($page-1)*$page_size.",$page_size";
$result=mysql_query($sql);
while($row=mysql_fetch_row($result)){
$rowset[]=$row;
}
}else{
$rowset=array();
}
//没有包含显示结果的代码,那不在讨论范围,只要用foreach就可以很简单的用得到的二维数组来显示结果
?>
4、OO风格代码
以下代码中的数据库连接是使用的peardb类进行处理
<?php
//FileName:Pager.class.php
//分页类,这个类仅仅用于处理数据结构,不负责处理显示的工作
ClassPager
{
var$PageSize;//每页的数量
var$CurrentPageID;//当前的页数
var$NextPageID;//下一页
var$PreviousPageID;//上一页
var$numPages;//总页数
var$numItems;//总记录数
var$isFirstPage;//是否第一页
var$isLastPage;//是否最后一页
var$sql;//sql查询语句
functionPager($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;
case1:
$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;}
}
returntrue;
}
/***
*
*返回结果集的数据库连接
*在结果集比较大的时候可以直接使用这个方法获得数据库连接,然后在类之外遍历,这样开销较小
*如果结果集不是很大,可以直接使用getPageData的方式获取二维数组格式的结果
*getPageData方法也是调用本方法来获取结果的
*
***/
functiongetDataLink()
{
if($this->numItems)
{
global$db;
$PageID=$this->CurrentPageID;
$from=($PageID-1)*$this->PageSize;
$count=$this->PageSize;
$link=$db->limitQuery($this->sql,$from,$count);//使用PearDB::limitQuery方法保证数据库兼容性
return$link;
}
else
{
returnfalse;
}
}
/***
*
*以二维数组的格式返回结果集
*
***/
functiongetPageData()
{
if($this->numItems)
{
if($res=$this->getDataLink())
{
if($res->numRows())
{
while($row=$res->fetchRow())
{
$result[]=$row;
}
}
else
{
$result=array();
}
return$result;
}
else
{
returnfalse;
}
}
else
{
returnfalse;
}
}
function_setOptions($option)
{
$allow_options=array(
"PageSize",
"CurrentPageID",
"sql",
"numItems"
);
foreach($optionas$key=>$value)
{
if(in_array($key,$allow_options)&&($value!=null))
{
$this->$key=$value;
}
}
returntrue;
}
}
?>
<?php
//FileName:test_pager.php
//这是一段简单的示例代码,前边省略了使用peardb类建立数据库连接的代码
require"Pager.class.php";
if(isset($_GET["page"]))
{
$page=(int)$_GET["page"];
}
else
{
$page=1;
}
$sql="select*fromtableorderbyid";
$pager_option=array(
"sql"=>$sql,
"PageSize"=>10,
"CurrentPageID"=>$page
);
if(isset($_GET["numItems"]))
{
$pager_option["numItems"]=(int)$_GET["numItems"];
}
$pager=@newPager($pager_option);
$data=$pager->getPageData();
if($pager->isFirstPage)
{
$turnover="首页|上一页|";
}
else
{
$turnover="<ahref="?page=1&numItems=".$pager->numItems."">首页</a>|<ahref="?page=".$pager-> PreviousPageID."&numItems=".$pager->numItems."">上一页</a>|";
}
if($pager->isLastPage)
{
$turnover.="下一页|尾页";
}
else
{
$turnover.="<ahref="?page=".$pager->NextPageID."&numItems=".$pager->numItems."">下一页</a>|<a href="?page=".$pager->numPages."&numItems=".$pager->numItems."">尾页</a>";
}
?>
需要说明的地方有两个:
这个类仅仅处理数据,并不负责处理显示,因为我觉得将数据的处理和结果的显示都放到一个类里边实在是有些勉强。显示的时候情况和要求多变,不如自己根据类给出的结果处理,更好的方法是根据这个Pager类继承一个自己的子类来显示不同的分页,比如显示用户分页列表可以:
<?php
ClassMemberPagerextendsPager
{
functionshowMemberList()
{
global$db;
$data=$this->getPageData();
//显示结果的代码
//......
}
}
///调用
if(isset($_GET["page"]))
{
$page=(int)$_GET["page"];
}
else
{
$page=1;
}
$sql="select*frommembersorderbyid";
$pager_option=array(
"sql"=>$sql,
"PageSize"=>10,
"CurrentPageID"=>$page
);
if(isset($_GET["numItems"]))
{
$pager_option["numItems"]=(int)$_GET["numItems"];
}
$pager=@newMemberPager($pager_option);
$pager->showMemberList();
?>
第二个需要说明的地方就是不同数据库的兼容性,在不同的数据库里截获一段结果的写法是不一样的。
mysql:select*fromtablelimitoffset,rows
pgsql:select*fromtablelimitmoffsetn
......
所以要在类里边获取结果的时候需要使用peardb类的limitQuery方法。
相关文章
- PHP时区设置相差8小时间程序与php.ini配置方法
- PHP脚本运行时间:
- php连接ldap服务器,使用PHP连接LDAP服务器[通俗易懂]
- 『抛弃MySQL,转用PHP新时代』(php废弃mysql)
- 安装Linux下的PHP环境(linux中安装php)
- 实现PHP与MongoDB的桥梁:连接数据库(php连接mongodb)
- 使用PHP执行Linux脚本:简单而快速!(php执行linux脚本)
- php在Linux上使用Yaf框架开发PHP应用(yaflinux)
- 简单易学,PHP与MySQL开发初窥门径(php与mysql开发)
- 文件MySQL更新实现快速PHP文件升级(mysql更新php)
- 使用PHP与MySQL结合开发数据库应用(phpmysql结果集)
- 深入理解MySQL转义在PHP中的应用技巧(mysql转义php)
- PHP如何连接MSSQL数据库?(php连接mssql)
- 让Linux帮助启动PHP服务(linux启动php)
- MongoDB整合PHP:快速配置你的开发环境(mongodb配置php)
- PHP与MSSQL架构构建的网站系统实践(php mssql 架构)
- Linux环境下的PHP脚本开发与应用(linux下php脚本)
- PHP与MySQL的更新:让Web应用更稳定!(php mysql 更新)
- PHP的FTP学习(二)
- 需要使用php模板的朋友必看的很多个顶级PHP模板引擎比较分析
- 利用Memcached在php下实现session机制替换PHP的原生session支持
- PHP开发中常用的字符串操作函数
- php入门学习知识点一PHP与MYSql连接与查询
- 解析php中session的实现原理以及大网站应用应注意的问题
- php中的PHP_EOL换行符详细解析
- php中mysql连接和基本操作代码(快速测试使用,简单方便)
- 2个比较经典的PHP加密解密函数分享
- php的XML文件解释类应用实例