其实很简单的
CEIL
CEIL
解决方案 »
- htaccess转为iis下面的httpd.ini中的重写
- 请教个rewrite规则 apache 的
- 找数组A里的值不在数组B里
- Call to a member function fetch_assoc() on a non-object
- 谁能帮忙解决IIS支持PHP的配置问题
- 关于if的错误, unexpected T_IF, expecting ')'
- 有没有什么查看php源代码的的工具
- $oFCKeditor->InstanceName = 'EditorDefault' ; 这句话有什么用?
- 初来乍到,多问几个弱问题没事吧:)
- 关于页面跳转的问题
- session_start()出问题了!急救啊!!!!!!!!!!
- 这是什么错误呀~~~~~~!!!!!!!各位帮忙看看!!!!!
<?php
echo ceil(4.3); // 5
echo ceil(9.999); // 10
?>
用你的总记录条数除以每页记录数并进一取整,就得到页数
剩下来就是while ....等流程控制了
..............
if( isset($_GET['page']) ){
$page = intval( $_GET['page'] );
}
else
$page = 1;
$sql="select count(*) as amount from table";
$query=mysql_query($sql);
$row = mysql_fetch_array($query);
$total=$row["amount"];
$pagesize=10;
if ($total){
if ($total<$pagesize)
$pagecount=1;
if ($total%$pagesize)
$pagecount=(int)($total/$pagesize)+1;
else $pagecount=$total/$pagesize;
}
else $pagecount=0;
$pagestring="";
$select="";
if ($page==1)
$pagestring.="首页|上一页|";
else $pagestring.="<a href=?page=1>首页</a>|<a href=?page=".($page-1).">上一页</a>|";
if ($page==$pagecount or $pagecount==0)
$pagestring.="下一页|尾页";
else $pagestring.="<a href=?page=".($page+1).">下一页</a>|<a href=?page=".($pagecount).">尾页</a>";
$begin=($page-1)*$pagesize;
$sql="select 字段1,字段2 from table limit $begin,$pagesize";
$query=mysql_query($sql);
while($row=mysql_fetch_array($query)){
echo $row["字段1"];
echo $row["字段2"];
}
.............
?>
分页显示详解
--------------------------------------------------------------------------------
作者:夜猫子 来源:超越PHP
1、前言分页显示是一种非常常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之一。对于web编程的老手来说,编写这种代码实在是和呼吸一样自然,但是对于初学者来说,常常对这个问题摸不着头绪,因此特地撰写此文对这个问题进行详细的讲解,力求让看完这篇文章的朋友在看完以后对于分页显示的原理和实现方法有所了解。本文适合初学者阅读,所有示例代码均使用php编写。2、原理所谓分页显示,也就是将数据库中的结果集人为的分成一段一段的来显示,这里需要两个初始的参数:每页多少条记录($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方法。
--------------------------------------------------------------------------------
作者:steeven
似乎讨论分页的人很少,难道大家都沉迷于limit m,n?
在有索引的情况下,limit m,n速度足够,可是在复杂条件搜索时,
where somthing order by somefield+somefield
mysql会搜遍数据库,找出“所有”符合条件的记录,然后取出m,n条记录。
如果你的数据量有几十万条,用户又搜索一些很通俗的词,
然后要依次读最后几页重温旧梦mysql该很悲壮的不停操作硬盘。所以,可以试着让mysql也存储分页,当然要程序配合。
(这里只是提出一个设想,欢迎大家一起讨论)ASP的分页:在ASP系统中有Recordset对象来实现分页,但是大量数据放在内存中,而且不知道什么时候才失效(请ASP高手
指点).
SQL数据库分页:用存储过程+游标方式分页,具体实现原理不是很清楚,设想如果用一次查询就得到需要的结果,或者是
id集,需要后续页时只要按照结果中的IDs读出相关记录。这样只要很小的空间保留本次查询的所有IDs. (SQL中的查询结
果不知道怎样清楚过期垃圾?)这样,可以让mysql模拟存储分页机制:
1. select id from $table where $condition order by $field limit $max_pages*$count;
查询符合条件的IDs.
限定最大符合条件的记录数量,也可以不加。
2. 因为php在执行结束后所有变量都要lost,所以可以考虑:
方案a. 在mysql建立临时表,查询结果用一个时间或随机数作为唯一标志插入。
其中建立page1~pagen个字段,每个字段保存该页中需要的ids, 这样一个id对一条记录.
方案b. 如果打开session,也可以放在session中保存,实际上是放在文件中保存。
建立一个$IDs数组,$IDs[1]~$IDs[$max_pages]. 考虑到有时候用户会开几个
窗口同时查询,要为$ids做一个唯一标志,避免查询结果相互覆盖。二维数组
和$$var都是好办法。
3. 在每页页的请求中,直接找到对应的IDs,中间以","间隔:
select * from $table where id in ($ids); 速度绝对快
4. 收尾要考虑查询结果的自动清除,可以设置定时或者按比例随机清楚。如果用mysql临时表要加上一个时间标志字段,
session中要加入$IDs["time"]=time(); 在一定时间以后不操作视为过期数据。5. 如果要优化,可以考虑用把1和2.a中的语句合并成select ...... into ....Note:
1.以上只是针对mysql的修补方案,希望mysql哪天能把这些功能加进去
2.其它数据库也可以套用。
3.如果其它数据库还有更先进的分页方式,请告诉我或mailto: [email protected]
4.如果真的有很多数据要查询,还是和mysql再见吧,sql,oracle都提供了更先进的关键词索引查询。精益求精,以上只是抛砖引玉,欢迎共同探讨分页问题。(也可关于其它数据库)
希望有一天能把各种分页方式整理出来供新手参考。
更多的请:
http://phpe.net/articles/374.shtml
巨快,分页演示,通用表维护
http://www.adr.gov.cn/download/panyuguang/adrnew/dict_List.asp
下载
http://www.adr.gov.cn/download/panyuguang/adrnew.rar
$pages=intval($rownum/$pagesize); //$rownum是总行数,$pagesize是分页大小
if($rownum%$pagesize) //$pages是总页数
$pages++;
switch($type)
{ case 1 :
$name="古典小说";
break;
case 2:
$name="诗词曲赋";
break;
case 3 :
$name="诸子百家";
break;
case 4:
$name="资治通鉴";
break;
case 5 :
$name="资治通鉴续";
break;
case 6:
$name="历史演义";
break;
} ?>
<?
define(ROWS, 20);function browse($scriptName,
$connection,
$rowOffset,
$query,
$ty,
$pageHeader,
$header)
{
// (1) Run the query on the database through the
// connection
$result = @ mssql_query ($query, $connection);
// Find out how many rows there are
$rowsFound = @ mssql_num_rows($result); // Is there any data?
if ($rowsFound != 0)
{
// Yes, there is data. // (2a) The "Previous" page begins at the current
// offset LESS the number of ROWS per page
$previousOffset = $rowOffset - ROWS; // (2b) The "Next" page begins at the current offset
// PLUS the number of ROWS per page
$nextOffset = $rowOffset + ROWS; // (3) Seek to the current offset
mssql_data_seek($result, $rowOffset);
?>
<table cellspacing=0 bordercolordark=#FFFFFF width="95%" bordercolorlight=#000000 border=1 align="center" cellpadding="2"><?
// (4b) Print out the column headers from $header
?>
<tr bgcolor="#6b8ba8" style="color:FFFFFF">
<td width="13%" height="19" align="center" valign="bottom" bgcolor="#6B8BA8"><span class="style1">类别</span></td>
<td width="26%" align="center" valign="bottom"><span class="style1">书名</span></td>
<td width="16%" align="center" valign="bottom"><span class="style1">作者</span></td>
<td width="9%" align="center" valign="bottom"><span class="style1">阅读次数</span></td>
</tr>
<? // (5a) Fetch one page of results (or less if on the
// last page)
for ( $rowCounter = 0;
(($rowCounter < ROWS) &&
($row = @ mssql_fetch_array($result)) );
$rowCounter++)
{
// Print out a row
//echo "\n<tr>";
//----------以下为修改后的内容
$path=trim($row['path']);
?>
<tr>
<td align="center" height="19"><? echo "<span class=\"style1\">[".trim($row['type'])."]</span>";?></td>
<td align="center" ><? echo "<a href=book.php?id=".$row['bid']." target='parent'>".trim($row['bname'])."</a></span>";?></td>
<td align="center"><? echo "<span class=\"style1\">".trim($row['author'])."</span>";?></td>
<td align="center"><? echo "<span class=\"style1\">".trim($row['btime'])."</span>";?></td>
</tr>
<?
//} // end foreach attribute echo "\n</tr>\n";
} // end for rows in the page // Finish the results table, and start a footer
echo "\n</table>\n<br>"; // (6) Show the row numbers that are being viewed
echo "当前为第".($rowOffset + 1) . "到" .
($rowCounter + $rowOffset) . "部 ";
echo "此类别共有书".$rowsFound. "部\n<br>"; // (7a) Are there any previous pages?
if ($rowOffset > 0)
// Yes, so create a previous link
echo "\n\t<a href=\"" . $scriptName .
"?offset=" . rawurlencode($previousOffset) .
"&type=$ty".
"\">上一页</a> ";
else
// No, there is no previous page so don't
// print a link
echo "上一页 ";
for($x=0, $page=1;
$x<$rowsFound;
$x+=ROWS, $page++)
// Is this the current page?
if ($x < $rowOffset ||
$x > ($rowOffset + ROWS - 1))
// No, so print out a link
echo "<a href=\"" . $scriptName .
"?offset=" . rawurlencode($x) .
"&type=$ty" .
"\">" . $page . "</a> ";
else
// Yes, so don't print a link
echo $page . " "; // (7b) Are there any Next pages?
// (7b) Are there any Next pages?
if (($row != false) && ($rowsFound > $nextOffset))
// Yes, so create a next link
echo "\n\t<a href=\"" . $scriptName .
"?offset=" . rawurlencode($nextOffset) .
"&type=$ty".
"\">下一页</a> ";
else
// No, there is no next page so don't
// print a link
echo "下一页"; } // end if rowsFound != 0
else
{
echo "<br>没有符合条件的页面.\n";
}
// (7c) Create a link back to the query input page
echo "<br><a href=books.php?type=$ty>返回</a><br>";
} //"?offset=" . rawurlencode($nextOffset) .
//"&type=$ty". // Untaint the user data
//$regionName = clean($regionName, 30); $scriptName = "books.php"; // Is there any user data?
// No, so show the <form> // Yes, there is user data so show the results
// Connect to the DBMS
if (!($connection = @ mssql_connect("nsssdd-server",
"sa",
"nsssdx")))
die("系统错误!!"); mssql_select_db("subedu", $connection);
// Set $offset to zero if not previously set
if (empty($offset))
$offset = 0;
// Build the query
$query = "SELECT type,bid,bname,author,btime from book where type='$name'";
// Initialize the browse() function parameters
// Query prefix for the next/previous links
// Page header for the browse screen
//$pageHeader = "图书列表";
// HTML <TABLE> column headers
/ //$header[1]["attrib"] = "bid";
browse($scriptName, $connection,
$offset, $query, $ty,
$pageHeader, $header);
// end if else user data
?>这个应该可以了
所以我的东西只好压着了,因为我的跟他的差不多.
不过这里唯一要提醒你的一点。如果你用的是最新的php+postgreeSQL7.3以上的话,
查询语句要改成
select * from table limit ($CurrentPageID - 1) * $PageSize offset $PageSize