打印

[php] mysql 数据库 分页类

本主题由 kuhanzhu 于 2008-3-28 09:19 提升


 提示:您可以先修改部分代码再运行
如果您加了新功能,或者是有改进,请与大家一起分享。


测试代码如下, db.php 请到这里下载 http://bbs.blueidea.com/thread-2841335-1-1.html
复制内容到剪贴板
代码:
<?php
    $db_config["hostname"]    = "127.0.0.1";    //服务器地址
    $db_config["username"]    = "root";        //数据库用户名
    $db_config["password"]    = "root";        //数据库密码
    $db_config["database"]    = "wap_blueidea_com";        //数据库名称
    $db_config["charset"]    = "utf8";
    $config["charset"]        = "utf-8";        //网站编码
    
    include('db.php');
    include('pagelist.php');
    $db    = new db();
    $db->connect($db_config);
    header("content-type:text/html;charset=".$config["charset"]);//设置页面编码
    $pl = new pagelist();
    $arr = $pl->get_rows('table_name');
    unset($pl);
    echo '<pre style="text-align:left">';
    print_r($arr);
    echo '</pre>';
    //指定特殊 sql 时候
    $pl = new pagelist();
    $sql = 'SELECT * FROM `wap_article` AS a, `wap_article_info` AS b WHERE a.id=b.articleid';
    $arr = $pl->get_rows_sql($sql);
    unset($pl);
    echo '<pre style="text-align:left">';
    print_r($arr);
    echo '</pre>';
?>
当表中的记录总数在 10000条以上时,使用了 子查询分页,这样效率会更高一些,数据量小的时候,直接查询更快。
这个是老王说的,参考这里: http://hi.baidu.com/thinkinginlamp/blog/item/c5dea0ecdfef5e392697910f.html

[ 本帖最后由 yytcpt 于 2008-3-27 17:13 编辑 ]
本帖最近评分记录
  • kuhanzhu 威望 +2 原创内容,谢谢分享。 2008-3-28 08:54
我不太喜欢将数据库操作和HTML输出部分封装到分页类型中
这样不好扩展 每次更改输出样式还需要修改类型 即便作为基类扩展使用 也会出现“脆鸡肋”效应

我写的分页类型如下 也请高手指教
复制内容到剪贴板
代码:
#    功  能: 页数列表类型
#    创建作者: Sanders Yao
#    修改作者: Sanders Yao
#    创建日期: 2007-12-25
#    修改日期: 2007-12-28
//======================================
// 必要常量:PAGELIST_MODE_ALL:        所有页数模式
// 必要常量:PAGELIST_MODE_FIX:        固定页数模式
// 必要常量:PAGELIST_MODE_MID:        中点页数模式
// 必要常量:PAGELIST_MODE_RANDOM:    随机页数模式
//======================================
define("PAGELIST_MODE_ALL", 0);
define("PAGELIST_MODE_FIX", 1);
define("PAGELIST_MODE_MID", 2);
define("PAGELIST_MODE_RANDOM", 3);
//======================================
// 类型:            pageList
// 功能:             获取页数列表
// 属性:
// @itsPage:        当前页数
// @itsLength:        页数列表长度
// @itsList:        页数列表
// @itsTotalPage:    总页数
// @itsOffset:        MySQL的LIMIT偏移量参数
// @itsPageBack:    前一页
// @itsPageNext:    后一页
// @itsListBack:    快退
// @itsListNext:    快进
//======================================
class pageList
{
    var $itsPage;
    var $itsLength;
    var $itsList;
    var $itsTotalPage;
    var $itsOffset;
    var $itsPageBack;
    var $itsPageNext;
    var $itsListBack;
    var $itsListNext;
    //======================================
    // 函数: pageList($num = 0, $perpage = 10, $page = NULL, $length = 10)
    // 功能: 构造函数
    // 参数: $num:        总记录数
    // 参数: $perpage:    每页记录数
    // 参数: $page:        页数
    // 参数: $length:    页数列表长度
    // 返回: 该类型的对象实例
    //======================================
    function pageList($num = 0, $perpage = 10, $page = NULL, $length = 10)
    {
        if($page)
        {
            $this->itsPage        = $page;
        }
        else
        {
            $this->itsPage        = isset($_GET["page"]) && is_numeric($_GET["page"]) && $_GET["page"] > 0
                ? $_GET["page"]
                : 1;
        }
        $this->itsLength    = $length;
        $this->itsTotalPage    = ceil($num / $perpage);
        $this->itsOffset    = ($this->itsPage - 1) * $perpage;
        $this->itsPageBack    = $this->itsPage > 1
            ? $this->itsPage - 1
            : 1;
        $this->itsPageNext    = $this->itsPage < $this->itsTotalPage
            ? $this->itsPage + 1
            : $this->itsTotalPage;
    }
    //======================================
    // 函数: getList($mode)
    // 功能: 构造函数
    // 参数: $mode:        列表模式
    // 参数: $ext:        扩展参数
    // 返回: 页数列表
    //======================================
    function getList($mode = PAGELIST_MODE_MID, $ext = NULL)
    {
        switch($mode)
        {
            case PAGELIST_MODE_ALL:
                $this->modeAll();
                break;
            case PAGELIST_MODE_FIX:
                $this->modeFix();
                break;
            case PAGELIST_MODE_MID:
                $this->modeMid();
                break;
            case PAGELIST_MODE_RANDOM:
                $this->modeRandom();
                break;
            default:
                $this->modeMid();
        }
        return count($this->itsList)
            ? $this->itsList
            : array(1);
    }
    //======================================
    // 函数: modeAll()
    // 功能: 获取所有页数
    // 参数: 无
    // 返回: 页数列表
    //======================================
    function modeAll()
    {
        $this->itsList    = array();
        for($i = 1;$i <= $this->itsTotalPage;$i ++)
        {
            $this->itsList[]    = $i;
        }
        return $this->itsList;
    }
    //======================================
    // 函数: modeFix()
    // 功能: 固定页数
    // 参数: 无
    // 返回: 页数列表
    //======================================
    function modeFix()
    {
        $this->itsList    = array();
        $start            = floor(($this->itsPage - 1) / $this->itsLength) * $this->itsLength + 1;
        $end            = $start + $this->itsLength - 1;
        $end            = $end > $this->itsTotalPage
            ? $this->itsTotalPage
            : $end;
        for($i = $start;$i <= $end;$i ++)
        {
            $this->itsList[]    = $i;
        }
        $this->itsListBack    = $start > 1
            ? $start - 1
            : $this->itsPage;
        $this->itsListNext    = $end < $this->itsTotalPage
            ? $end + 1
            : $this->itsPage;
        return $this->itsList;
    }
    //======================================
    // 函数: modeMid()
    // 功能: 中点页数
    // 参数: 无
    // 返回: 页数列表
    //======================================
    function modeMid()
    {
        $this->itsList    = array();
        if($this->itsLength % 2)
        {
            $frontHalf    = $backHalf        = floor($this->itsLength / 2);
        }
        else
        {
            $frontHalf    = $this->itsLength / 2;
            $backHalf    = $frontHalf - 1;
        }
        if($this->itsPage - $frontHalf < 1)
        {
            $start        = 1;
        }
        elseif($this->itsPage + $backHalf < $this->itsTotalPage)
        {
            $start        = $this->itsPage - $frontHalf;
        }
        else
        {
            $temp        = $this->itsPage - $frontHalf - $backHalf + $this->itsTotalPage - $this->itsPage;
            $start        = $temp < 1
                ? 1
                : $temp;
        }
        if($this->itsPage + $backHalf > $this->itsTotalPage)
        {
            $end        = $this->itsTotalPage;
        }
        elseif($this->itsPage - $frontHalf > 1)
        {
            $end        = $this->itsPage + $backHalf;
        }
        else
        {
            $temp        = $this->itsPage + $backHalf + $frontHalf - $this->itsPage + 1;
            $end        = $temp > $this->itsTotalPage
                ? $this->itsTotalPage
                : $temp;
        }
        for($i = $start;$i <= $end;$i ++)
        {
            $this->itsList[]    = $i;
        }
        $this->itsListBack    = $this->itsPage - $this->itsLength > 1
            ? $this->itsPage - $this->itsLength
            : 1;
        $this->itsListNext    = $this->itsPage + $this->itsLength < $this->itsTotalPage
            ? $this->itsPage + $this->itsLength
            : $this->itsTotalPage;
        return $this->itsList;
    }
    //======================================
    // 函数: modeRandom()
    // 功能: 随机页数
    // 参数: 无
    // 返回: 页数列表
    //======================================
    function modeRandom()
    {
        $all                = $this->modeAll();
        $this->itsList        = array();
        list($sec, $usc)    = explode(" ", microtime());
        srand($usc);
        shuffle($all);
        $end                = $this->itsTotalPage - 1 > $this->itsLength
            ? $this->itsLength
            : $this->itsTotalPage - 1;
        for($i = 0;$i <= $end;$i ++)
        {
            $temp    = array_shift($all);
            if($this->itsPage != $temp)
            {
                $this->itsList[]    = $temp;
            }
            else
            {
                $this->itsList[]    = array_shift($all);
            }
        }
        return $this->itsList;
    }
}
本帖最近评分记录
  • kuhanzhu 威望 +2 原创内容,谢谢分享 2008-3-28 10:50
新手
没错。子查询是可以提高查询效率,特别是在总计数数很大的时候。。一般超过5000就可以使用子查询了。
美狗
1楼类中的 get_rows_by_sql() 函数写错了,请更新为这个。
复制内容到剪贴板
代码:
<?php
        function get_rows_by_sql($sql=''){
            if ($sql) {
                $this->sql = $sql." LIMIT ".$this->page_size*($this->page-1).", ".$this->page_size;    //指定的SQL;
            }else{
                $this->get_sql();
            }
            return $this->db->row_query($this->sql);
        }
?>
版主看到了,请帮忙更新一下1楼的帖子,谢谢。

TOP

还在为头像烦恼?还在为不能关注好友动态烦忧?快来蓝色理想家园吧!
请问楼主,我使用了特定sql语句进行分页的时候,只可以显示第一页,不能向后翻页。

我刚接触类,不太懂,不知道是不是是不是我这边写错了。但我用get_rows就可以向后翻页。
复制内容到剪贴板
代码:
<?
//省略了db建立
$pl=new pagelist();
$pl->page_size=$g_out['pagesize'];
$sql='select count(*) from `notes` where `userid`=$userid order by id desc';
echo $pl->get_rows_sql($sql);
?>

TOP

终于找到问题

可能是因为我的MYsql版本原因,所以在
复制内容到剪贴板
代码:
//总记录数
        function set_total_records(){
            if ($this->total_records==0 or !isset($this->total_records)){
                if (empty($this->count_sql) and !empty($this->table["tablename"])){
                    $sql = "SELECT count(".$this->table["id"].") as count_id FROM `".$this->table["tablename"]."` ".($this->table["where"]!=""?" WHERE ".$this->table["where"]:"");
                }else{
                    $sql = preg_replace("/SELECT(.*?)FROM(.*?)/i", "SELECT count(a.id) AS count_id FROM\\2", $this->sql);
                }
                $arr = $this->db->row_query_one($sql);
                $this->total_records = $arr["count_id"];        
                
            }
        }
翻页后因为sql查询最后的limit 5,5而导致取不出总记录数

但取记录数用不的limit所以,可以把他用preg_replace去掉,得到:
复制内容到剪贴板
代码:
//总记录数
        function set_total_records(){
            if ($this->total_records==0 or !isset($this->total_records)){
                if (empty($this->count_sql) and !empty($this->table["tablename"])){
                    $sql = "SELECT count(".$this->table["id"].") as count_id FROM `".$this->table["tablename"]."` ".($this->table["where"]!=""?" WHERE ".$this->table["where"]:"");
                }else{
                    $sql = preg_replace("/SELECT(.*?)FROM(.*?)/i", "SELECT count(a.id) AS count_id FROM\\2", $this->sql);
                    $sql = preg_replace("/LIMIT(.*)/i","",$sql); //去掉limit
                }
                $arr = $this->db->row_query_one($sql);
                $this->total_records = $arr["count_id"];        
                
            }
        }
从而问题解决

TOP