简易分页类

WBOY
WBOYOriginal
2016-06-23 14:20:381790browse

这是一个简单易用的分页类。只需在你原有的程序中加两句、改一句就可以了
先贴代码
paging.php

<?phpclass Paging {  public static $count = 0;  public static $size = 0;  public static $page = 0;  static function prepare($sql, $pagesize=10) {    $page = isset($_GET['page']) ? $_GET['page'] : 1;    $pageon = ($page - 1) * $pagesize;    $sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";    $rs = mysql_query($sql);    $p = mysql_query('SELECT FOUND_ROWS()');    list(self::$count) = mysql_fetch_row($p);    self::$size = $pagesize;    self::$page = $page;    return $rs;  }  static function bar($tpl='') {    if(!$tpl) $tpl = '<a href=?reset>首页</a> <a href=?prve>上一页</a> <a href=?next>下一页</a> <a href=?end>尾页</a>';    $count = ceil(self::$count / self::$size);    $page = self::$page;    unset($_GET['page']);    $d = array(      'reset' => 1,      'prve' => $page > 1 ? $page - 1 : 1,      'next' => $page < $count ? $page + 1 : $count,      'end' => $count,    );    foreach($d as $k=>$v) {      $_GET['page'] = $v;      $tpl = str_replace($k, http_build_query($_GET), $tpl);    }    echo $tpl;  }}

通常你都有类似这样的语句
$sql =".....";
$rs = mysql_query($sql);

$rs = mysql_query("select ....");


你只需改作
include 'paging.php';
$rs = paging::prepare($sql, 每页行数);
在需要出现分页条的地方写入
paging::bar();

就可以了,非常简单!


回复讨论(解决方案)

前排拜模。
这样的写法还是第一次见到。
 $sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";

sql还用preg_replace……

闲着无事,来个js函数,娱乐一下

<!doctype html><html><meta charset=utf-8><script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script><style> .page a{  text-decoration:none;}.page a span{  padding:6px 17px 6px 17px;  border:1px solid #ABC;  color: #1155BB;  font-size:14px;  font-weight:bold;  font-family: 'helvetica neue', arial, sans-serif;}#Next{margin-left:5px;}.click_page{  background:#2266BB;  color:#ffffff; } .page a span:hover{   background:#3377CC;   color:#ffffff; }</style><body><ul id="myPage"> <li>aaaaaaaa1</li> <li>aaaaaaaa2</li> <li>aaaaaaaa3</li> <li>aaaaaaaa4</li> <li>aaaaaaaa5</li> <li>aaaaaaaa6</li> <li>aaaaaaaa7</li> <li>aaaaaaaa8</li> <li>aaaaaaaa9</li> <li>aaaaaaaa10</li> </ul> <div id="myDev"></div><script>function Paginate(pageDIV,parent,child,size){	var $pageDest = $(pageDIV);	var $mainTag = $(parent);	var mainContent = $mainTag.html();    var currentPage = 0;  //当前页    var pageSize = size;  //每页行数		var numRows = $mainTag.find(child).length; 	var numPages = Math.ceil(numRows/pageSize); //总页数	$mainTag.bind("repaginate", function() {		$mainTag.find(child).hide();	$mainTag.find(child).slice((currentPage*pageSize),(currentPage+1)*pageSize).show();	});		    var $pager = $("<div class='page'><a href='javascript:void(0)'><span id='Prev' style='margin-right:4px;'>&laquo; Prev</span></a></div>");    for( var page = 0; page < numPages; page++ )    {             $("<a href='javascript:void(0)'><span id='"+(page+1)+"'>"+ (page+1) +"</span></a>")           .bind("click", { "newPage": page }, function(event){                currentPage = event.data["newPage"];				$("#Prev").css({"background":"#FFF"});				$("#Next").css({"background":"#FFF"});				if(currentPage == 0 ){				$("#Prev").css({"background":"#c0c0c0"});				}else if(currentPage == (numPages-1)){								$("#Next").css({"background":"#c0c0c0"});				}                               $(this).children("span").attr("class","click_page").css({"color":"#FFFFFF"});                $(".page a span").not($(this).children("span")).attr("class","");                $(".page a span").not($(this).children("span")).css({"color":"#1155BB"});                $mainTag.trigger("repaginate");            })            .appendTo($pager);    }       var next=$("<a href='javascript:void(0)'><span id='Next'>Next &raquo;</span></a>");    $pager.append(next);    $pager.appendTo($pageDest);//显示分页条    $("#1").attr("class","click_page");    $("#1").css({"color":"#FFFFFF"});    $mainTag.trigger("repaginate");//初始化触发一次    $("#Prev").bind("click",function(){       var prev=Number($(".click_page").text()-2);       currentPage=prev;	   	   if(currentPage==0){				 $(this).css({"background":"#c0c0c0"});		}else if(currentPage<0) {                 return;		}			   $("#Next").css({"background":"#FFF"});           $("#"+(prev+1)).attr("class","click_page");       $("#"+(prev+1)).css({"color":"#FFFFFF"});       $(".page a span").not($("#"+(prev+1))).attr("class","");       $(".page a span").not($("#"+(prev+1))).css({"color":"#1155BB"});       $mainTag.trigger("repaginate");    });     $("#Next").bind("click",function(){	        var next=$(".click_page").attr("id");	          currentPage=Number(next);	   if((currentPage+1)>numPages) {	           return;       }else if((currentPage+1)==numPages) {                 $(this).css({"background":"#c0c0c0"});         }        $("#Prev").css({"background":"#FFF"});       $("#"+(currentPage+1)).attr("class","click_page");       $("#"+(currentPage+1)).css({"color":"#FFFFFF"});       $(".page a span").not($("#"+(currentPage+1))).attr("class","");       $(".page a span").not($("#"+(currentPage+1))).css({"color":"#1155BB"});		        $mainTag.trigger("repaginate");    });	 } Paginate("#myDev","#myPage","li",3); </script> </body> </html>

娱乐娱乐


谢谢分享,确实很方便  ,简单易用 。学习了。

用的是传统的$query=mysql_query("SELECT * FROM news  LIMIT $kaishi , 

10 ");
现在才发现还有这种写法..学习了

换一种调用写法,可能感觉要好些

include 'paging.php';$rs = mysql_paging_query($sql, 20);//替代 mysql_querymysql_paging_bar();//显示分页条
paging.php
class Paging {  private static $_Instance;  private function __clone(){}  public static function getInstance() {    if(empty(self::$_Instance)) self::$_Instance = new self();    return self::$_Instance;  }  protected $count = 0;  protected $size = 0;  protected $page = 0;  function prepare($sql, $pagesize=10) {    $page = isset($_GET['page']) ? $_GET['page'] : 1;    $pageon = ($page - 1) * $pagesize;    $sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";    $rs = mysql_query($sql);    $p = mysql_query('SELECT FOUND_ROWS()');    list($this->count) = mysql_fetch_row($p);    $this->size = $pagesize;    $this->page = $page;    return $rs;  }  function bar($tpl='') {    if(!$tpl) $tpl = '共{count}页 第{page}页 <a href=?{reset}>首页</a> <a href=?{prve}>上一页</a> <a href=?{next}>下一页</a> <a href=?{end}>尾页</a>';    $count = ceil($this->count / $this->size);    $page = $this->page;    $d = array(      '{reset}' => 1,      '{prve}' => $page > 1 ? $page - 1 : 1,      '{next}' => $page < $count ? $page + 1 : $count,      '{end}' => $count,      '{count}' => $count,      '{page}' => $page,    );    foreach($d as $k=>&$v) {      if(in_array($k, array('{reset}', '{prve}', '{next}', '{end}'))) {        $_GET['page'] = $v;        $v = http_build_query($_GET);      }    }    echo strtr($tpl, $d);  }}function mysql_paging_query($sql, $num=10) {  return Paging::getInstance()->prepare($sql, $num);}function mysql_paging_bar($tpl='') {  return Paging::getInstance()->bar($tpl);}

 收了好好研究,谢楼主

楼主的分析很棒

学习了。看着确实不错

定啊 ~~~

大牛写的,收了

好东西  mark 备用

数据库连接写在哪儿呢?

简单的是最好的

没学过php,但原理是一样的

先占位置,有机会凑个热闹。

不错啊,你从91年便开始从事计算,有没有烦忧过啊。真是不容易。

分页代码中有sql,唠叨老大你会误导初学者。

既然sql 都集成在paging 类中了,就顺便做了点扩展,支持查询.
分页代码中有sql,唠叨老大你会误导初学者。

//表单部分。<form method="post" action="#">   按标题: <input type="text" name="QueryLike[testTitle]" />    id大于: <input type="text" name="QueryMoreThan[testId]" />    <input type="submit"  value="搜索"/></form>

对原有的paging 类,做极小的改变.
//这里的代码,要和唠叨老大保持高度一致.header('Content-type:text/html; charset=utf-8');include 'parse.php';include 'convert.php';include 'pageparam.php';include 'page.php';$sql = "select testId,testTitle from test ";$rs = mysql_paging_query($sql, 5);//替代 mysql_query//调试,看查询结果!while($rows = mysql_fetch_object($rs)){    print("<pre class="brush:php;toolbar:false">");         print_r($rows);    print("
");}echo mysql_paging_bar();//显示分页条

下面开始,就是折腾的地方了。
class Paging {    private static $_Instance;    private function __clone(){}    public static function getInstance() {        if(empty(self::$_Instance)) self::$_Instance = new self();        return self::$_Instance;    }    protected $count = 0;    protected $size = 0;    protected $page = 0;    //extend by murain. 参数解析对象.    protected $paramParse;    function prepare($sql, $pagesize=10) {        $page = isset($_GET['page']) ? $_GET['page'] : 1;        $pageon = ($page - 1) * $pagesize;        //extend by murain.  改变一 得到sql语句..         $this->paramParse = new pageparam();        $sql = $this->paramParse->getSql($sql);        $sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";        $rs = mysql_query($sql);        $p = mysql_query('SELECT FOUND_ROWS()');        list($this->count) = mysql_fetch_row($p);        $this->size = $pagesize;        $this->page = $page;        return $rs;    }    function bar($tpl='') {        if(!$tpl) $tpl = '共{count}页 第{page}页 <a href=?{reset}>首页</a> <a href=?{prve}>上一页</a> <a href=?{next}>下一页</a> <a href=?{end}>尾页</a>';        $count = ceil($this->count / $this->size);        $page = $this->page;        $d = array(            '{reset}' => 1,            '{prve}' => $page > 1 ? $page - 1 : 1,            '{next}' => $page < $count ? $page + 1 : $count,            '{end}' => $count,            '{count}' => $count,            '{page}' => $page,        );        foreach($d as $k=>&$v) {            if(in_array($k, array('{reset}', '{prve}', '{next}', '{end}'))) {         //改变二,分类的超链接.                  $v = $this->paramParse->makePageItem($v);             }        }        return  strtr($tpl, $d);    }}

如果,就很easy 的支持了表单的查询. 这里仅做了两个基本的例子,一个like 查询,一个是 >= 查询.
这样当你有查询需要的变化时,只用把查询表单的命名更改一下即可.

下面就是扩展类了,有兴趣的慢慢看。欢迎指导拍砖。
pageparam.php
<?phpclass pageparam{    protected $parser;    protected $serchparam;    protected $convert;    public function __construct()    {        //参数解析.        if( strtolower($_SERVER['REQUEST_METHOD']) == 'post'){            $this->parser = new postParse();        }else {            $this->parser = new getParse();        }        $this->serchparam = $this->parser->parse(); //得到查询参数.        $this->qConvert = new queryConvert( $this->serchparam );    }    /**     * 处理sql 查询条件     * @param $sql     */    public function getSql( $sql )    {        list( $where  , $order ) = $this->qConvert->convert();        $whereString = "";        if( !preg_match( "/where/i" , $sql))        {             $whereString = " where 1=1";        }        foreach($where as $whereItem):            $whereString .= " and $whereItem";        endforeach;        $sql .= $whereString;;        return $sql;    }    public function makePageItem($v)    {        $v = "page=$v";        unset(  $this->serchparam["page"]  );        foreach ( $this->serchparam as $key =>$val):           $v .= "&$key=$val";         endforeach;        return $v;    }    public static  function encode( $str){        $src  = array("/","+","=");  $dist = array("-a","-b","-c");    $old  = base64_encode($str); $new  = str_replace($src,$dist,$old);        return $new;    }    public static function decode( $str) {        $src = array("-a","-b","-c");   $dist  = array("/","+","=");   $old  = str_replace($src,$dist,$str);    $new = base64_decode($old);        return $new;    }}


parse.php
<?php/*获取参询参数的接口*/interface iParse{  function parse();}class getParse implements iParse{private $_params;function parse(){$this->setParam( $_GET );return $this->getParam();}//设置与获取参数function setParam( $_param ) {  $this->_params = $_param;  }function getParam() {   return $this->_params;  }}class postParse implements iParse{private $_params = array();private $_postParam;private $_ParseItem;  //解析序列const PARSE_ARRAY_INTERVAL_WORD = "-_-";public function parse(){    $params = $_POST;    $this->setParams($params);    return $this->getParams();}function __construct(){    $itemArr = array(           "QueryLike" => "CommonParse"        ,  "QueryMoreThan" => "CommonParse"        ,  "QueryIn" => "ArrayParse"    );    $this->setParseItem($itemArr);}private function setParseItem($itemArr)  { $this->_ParseItem = $itemArr;  }private function setParams( $params = array() ) {    $this->_postParam = $params;    foreach( $this->_ParseItem as $key=>$handle):    $this->$handle( $key );    endforeach;}private function getParams() {return $this->_params;}private function  CommonParse($key) {  //单值参数解析.$$key = isset( $this->_postParam[$key])? $this->_postParam[$key]:"";   //终于用了一次$$if(is_array($$key))://遍历所有的参数,为空的不参与搜索,后期交由handle去处理.foreach ($$key as $key2 => $value):if (trim($value) == "") unset($$key[$key2]);    //删除搜索条件中值为空的参数else {$value = pageparam::encode($value);$this->_params +=  array($key."_".$key2=>"$value");}endforeach;endif;}private function ArrayParse($name) {  //数组参数解析  通常为checkbox.foreach($this->_postParam as $key => $val):if(preg_match("/$name/i",$key)){$str_val =  array();  //生成parm所用参数数组.$str_cond = array();  //生成查询条件数组.$key_piece = str_replace("$name"."_","",$key);  //找出mul 部分.if(sizeof($_POST["$key"]) >0):foreach($_POST["$key"] as $val) {$str_val[]= pageparam::encode($val);  //生成parm所用参数数组.$str_cond []= "$key_piece = '$val'  ";  //生成查询条件数组.}$str_mul = implode( self::PARSE_ARRAY_INTERVAL_WORD ,$str_val);   $this->_params[$key] = $str_mul; //合并生成parameters.endif;}endforeach;}}



看来是写的很不精简了,有空优化一下,还有一个。
convert.php

abstract class converAbstract{    private $_params;    private $_iConvertHandle;    public $queryCond = array();    function __construct($param)    {        $this->setParams($param);    }    /**     * 设置待转换参数。     * @param $params     */    public function setParams($params) { $this->_params = $params; }    public function getParams() {   return $this->_params;  }    abstract function convert();    public function getKeyValue($key)    {        //pr($key,"正在解析字段名");        preg_match_all("/(Query[^_]+)_([\w-]+)/i",$key,$match);        if(!$match[0]){            $match[1][0] = $key;            $match[2][0] = "";        }        //  pr($match,"解析后的值");        return array($match[1][0],$match[2][0]);    }    /**     * 设置转换器接口     * @param $handle     */    public function setConvertHandle($handle)    {        $handleClsString = $handle;        $this->_iConvertHandle = new $handleClsString();    }    /**     * 得到转换器接口     * @return mixe     */    public function getConvertHandle()    {        return $this->_iConvertHandle;    }}class queryConvert extends converAbstract{    function __construct($param)    {        parent::__construct( $param);    }    /**     * 实现 convert 接口.     */    function convert()    {        $params = $this->getParams();        foreach ($params as $key => $val):            //得到查询条件.            list($queryHandle, $queryKey) = $this->getKeyValue($key);            if (preg_match("/Query/i", $queryHandle)):                $this->setConvertHandle($queryHandle . "ConvertHandle");  //设置查询条件接口转换器.                //KDG::pr( $queryKey , "得到的对应的数.");                if ($queryKey):                    $temp = $this->getConvertHandle()->convert2Query($queryKey, $val);                    if (is_array($temp)):                        $this->mergeData($temp);                    endif;                endif;            endif;        endforeach;        return array($this->queryCond,$this->order);     }    /**     *     * 归并查询数组     * @param unknown_type $arr     */    function mergeData($arr)    {        foreach ($arr as $key => $val):            if (!array_key_exists($key, $this->queryCond)) {                $this->queryCond += $arr;            }            else {                if (is_int($key)) { //Patch for the merget the QueryCondArr conflict!                    $this->queryCond [] = $val;                    continue;                }                $this->queryCond [$key] = array_merge($this->queryCond [$key], $val);            }        endforeach;    }}interface iConvertHandle{    function convert2Query($key,$val);  //转换至查询条件}//like 查询转换class QueryLikeConvertHandle implements iConvertHandle {    function convert2Query($key,$val)  //转换至查询条件    {        $queryCond = array();        $queryCond []= "$key like '%" . pageparam::decode($val) . "%'";        return $queryCond;    }}//大于等于查询条件转换class QueryMoreThanConvertHandle implements iConvertHandle {    function convert2Query($key,$val)  //转换至查询条件    {        $queryCond = array();        $queryCond []= "$key >= '".trim(pageparam::decode($val) ) ."'";        return $queryCond;    }}

mysql的分页,语法都直接支持了:limit m,n
mssql是2012才有fetch ...,之前一直仅仅是一半功能的top n或大动干戈的row_number()

不错。很值得学习。

挺有?意的一??法,有??把我的分??改一下.

感觉不要把sql都写里面去啊好些啊。。
分页类传个总数跟当前页码与页码的url或分析生成页码列表就好了。

另,
$sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";
sql有两个select应该有问题了吧? 加个1参数...

是哦,从设计原理上说,把SQL写到分页不好。
分页就分页。获取数据就获取数据

www.dcrcms.com我写的小CMS里有分页类的。include/class/class.page.php 也可以看看

有demo吗

是哦,从设计原理上说,把SQL写到分页不好。
分页就分页。获取数据就获取数据
www.dcrcms.com我写的小CMS里有分页类的。include/class/class.page.php 也可以看看
精简的代码更方便传播,至于具体写在内在外。 我认为遵守的原则是多用组合。  

没人担心过 SQL_CALC_FOUND_ROWS 的效率吗?

这个曾测试,很多情况下没有mysql文档说的那么漂亮

本人不懂编程,不懂什么语言,完全不知道PHP是何物。就光看了wordpress的官网,还有网上下个淘宝客模板,乱搞了个博客。但是觉得很累。全部都是要手动添加,有没有自动采集的?

收藏了~

学习了,好久没有看到这样的帖子了

有空也写个。
楼上的都是高手。

只希望初学者不要被误导。

1 函数通常是公共部分,因此依赖的参数尽量数量少,简单,无论是网站架构还是代码架构,独立性可以做一个指标,依赖的东西越少越好。
2 非常不利代码重构。

我很难想像一个项目中把sql弄的那都是,迅速解决线上BUG,快速完成产品需求,良好的代码结构是少不了的,通常网站多多少少会使用mvc,也就是说通常会封装mysql类,还会有一个model类,最后开发会以model为基类写出我们的业务逻辑类。 如果你把sql写入分页类。你可能就会舍弃这些,如果你两个都用,我很怀疑你技术经理怎么做的代码架构,也许吧!公司很民主,但绝对是很糟的事。

也许有一天你的数据库要做调整,为什么?没事闲的?因为数据量太大了。要做分表处理,拿csdn来说,我发布的贴子做了按年份处理(也许还按论坛做了分库处理,个人的猜想)。分页通常不会在一处调用,这个取决产品需求。也就说你要改的地方不止一处。而且我现在还要做分库处理,要使用主从。也就是说要区分mysql的连接,因此大家使用mysql_query时,把第二个参数也带上,再使用MVC时,可以很好解决这个问题。

这是一个简单易用的分页类。只需在你原有的程序中加两句、改一句就可以了
先贴代码
paging.php
PHP code
class Paging {
  public static $count = 0;
  public static $size = 0;
  public static $page = 0;
  static function prepare($sql, $……

        不太会用,不知道怎么用分页,麻烦楼主帮我弄下可以么?很简单的
我的代码

   aa.php

$con = mysql_connect("localhost","root","123456");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("qq", $con);

$result = mysql_query("SELECT * FROM abc");

echo "







";

while($row = mysql_fetch_array($result))
  {
  echo "";
  echo "";
  echo "";
   echo "";
    echo "";
  echo "";
  }
echo "
qq jiage lirun shijian
" . $row['qq'] . "" . $row['jiage'] . "" . $row['lirun'] . "" . $row['shijian'] . "
";

mysql_close($con);
?>

这段代码是是将数据库里面的数据取出来,然后以表格形式输出来,可是如果数据库的数据过多,表格就会越来越长。。所以我想弄个分页,只显示5条信息,如果想看第六条就要 下一页  
能帮我弄下么?!

本帖最后由 xuzuning 于 2012-09-01 19:08:56 编辑

include 'paging.php';
$con = mysql_connect("localhost","root","123456");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("qq", $con);

//$result = mysql_query("SELECT * FROM abc");
$result = mysql_paging_query("SELECT * FROM abc", 20);//每页20 行


mysql_paging_bar();//显示分页条 上面来一个

echo "





";

while($row = mysql_fetch_array($result))
  {
  echo "";
  echo "";
  echo "";
  echo "";
  echo "";
  echo "";
  }
echo "
qq jiage lirun shijian
" . $row['qq'] . "" . $row['jiage'] . "" . $row['lirun'] . "" . $row['shijian'] . "
";
mysql_paging_bar();//显示分页条 下面也来一个
mysql_close($con);

简单吧?很简单

php看不懂

include 'paging.php';
$con = mysql_connect("localhost","root","123456");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("qq", $con);

//$result = mys……
太感谢亲了。。。我自己研究下。。。如何调用。。至于你上面的暂时不会呵呵。。。太感谢了

这种静态方法是不是比用this来实例化对象要速度快呢,我之前学的分页类写的老长的..老大

收藏了~

$sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";
版主,上面这话代码是做什么的?

$sql = preg_replace('/select\s/i', '$0SQL_CALC_FOUND_ROWS ', $sql) . " limit $pageon, $pagesize";
版主,上面这话代码是做什么的?
将传入的 sql 指令串改为形如
select SQL_CALC_FOUND_ROWS * from ..... limit 1,10
这样的指令串, limit 子句就不需要解释了吧?
SQL_CALC_FOUND_ROWS 参数可计算出全部符合条件的记录数,随后可用 SELECT FOUND_ROWS() 取回
不然你为取得全部符合条件的记录数,不也是要 select count() ...一下吗?
#33 的担忧是无意义的
SELECT FOUND_ROWS() 必然比 select count() .... 快,因为他不再需要遍历数据了

当然,有 SQL_CALC_FOUND_ROWS 是要比无 SQL_CALC_FOUND_ROWS 慢一些的

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn