weecl专栏

wecl的专栏

adodb分页函数初读

 
用了adodb有段时间了,发现还没有对adodb还很不了解,今天特地看了下adodb的分页函数,在此记录下,遗漏或不对的地方希望看到这个文章的朋友们能够指正和讨论。
 
在adodb中,声明一个对象($obj_db)后,我们就可以通过对象来调用pageExecute函数($obj_db->pageExecute($sql,$pagesize,$currentpage,$inputarr, $secs2cache)),一般情况下,都只使用到了前三个参数,后面两个参数都有默认值,可以在需要时传值使用。
 

    
function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0
    {
 
pageExecute函数:在pageExecute函数里,通过判断全局变量$ADODB_INCLUDED_LIB是否设定,没有设定则包含adodb-lib.inc.php文件。

        
global $ADODB_INCLUDED_LIB;
        
if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
判断类成员pageExecuteCountRows,选择调用不同的函数。
//adodb的默认设置  $pageExecuteCountRows = true;
        
if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
        
else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
在这里就说_adodb_pageexecute_all_rows函数吧。在_adodb_pageexecute_all_rows 里调用_adodb_getcount函数,返回影响的记录条数,通过ceil计算总共页数。
    $qryRecs = false//count records for no offset
    
    
$qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
    
$lastpageno = (int) ceil($qryRecs / $nrows);
    
$zthis->_maxRecordCount = $qryRecs;
设置一系列变量后,
    // a page number greater than the last page number.
    if ($page >= $lastpageno) {
        
$page = $lastpageno;
        
$atlastpage = true;
    }
    
    
// If page number <= 1, then we are at the first page
    if (empty($page|| $page <= 1) {    
        
$page = 1;
        
$atfirstpage = true;
    }
通过判断变量$secs2cache,使用不同函数。刚刚上面也已经提到,这个$secs2cache是不经常使用的(默认值为0),所以一般调用的函数就是SelectLimit函数。

    
$offset = $nrows * ($page-1);
    
if ($secs2cache > 0
        
$rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
    
else 
        
$rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
 
SelectLimit函数:读到这个函数就感觉很高兴了,因为它返回的结果就是我们分页时各个页面的结果。
    function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
    {
进入函数就有一个判断,是否支持top功能 及 行数是否大于0(每页行数)
if ($this->hasTop && $nrows > 0) {
,如果两个条件都满足,则进行判断是mssql数据库还是access数据库。紧接着下面的又是个判断,感觉这个判断是比较重要的。判断偏移量($offset)是否大于0,也就是当你不在分页页面的第一页时,这个$offset将会是大于0的。在两个判断里都使用了正则替换。此正则也不难理解,就是将 select 或select distinct 或select distinctrow 替换成 select top n 或 select distinct top n 或 select distinctrow top n。当$offset 大于 0 时 ,通过$nrows + $offset得到要选择的数据数量。
if ($offset <= 0) {                
                    
// access includes ties in result
                    if ($isaccess) {
                        
$sql = preg_replace(
                        
'/(^s*selects+(distinctrow|distinct)?)/i','/1 '.$this->hasTop.' '.$nrows.' ',$sql);

                        
if ($secs2cache>0) {
                            
$ret =& $this->CacheExecute($secs2cache, $sql,$inputarr);
                        } 
else {
                            
$ret =& $this->Execute($sql,$inputarr);
                        }
                        
return $ret// PHP5 fix
                    } else if ($ismssql){
                        
$sql = preg_replace(
                        
'/(^s*selects+(distinctrow|distinct)?)/i','/1 '.$this->hasTop.' '.$nrows.' ',$sql);
                    } 
else {
                        
$sql = preg_replace(
                        
'/(^s*selects)/i','/1 '.$this->hasTop.' '.$nrows.' ',$sql);
                    }
            } 
else {
                
$nn = $nrows + $offset;
                
if ($isaccess || $ismssql) {
                    
$sql = preg_replace(
                    
'/(^s*selects+(distinctrow|distinct)?)/i','/1 '.$this->hasTop.' '.$nn.' ',$sql);
                } 
else {
                    
$sql = preg_replace(
                    
'/(^s*selects)/i','/1 '.$this->hasTop.' '.$nn.' ',$sql);
                }
            }
调用Execute 函数执行上面返回的sql,
            
        
if ($offset>0){
            
if ($secs2cache>0$rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
            
else $rs = &$this->Execute($sql,$inputarr);
        } 
else {
            
if ($secs2cache>0$rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
            
else $rs = &$this->Execute($sql,$inputarr);
        }
执行成功后,将返回的对象作为参数传递给_rs2rs 函数。
        if ($rs && !$rs->EOF) {
            
$rs =& $this->_rs2rs($rs,$nrows,$offset);
        }
 
_rs2rs 函数:还是少不了if,判断$rs 对象是否有值,否则返回false。
        if (! $rs) {
            
$false = false;
            
return $false;
        }
判断数据库类型,没有设置,则返回 上面 的$rs对象。
        $dbtype = $rs->databaseType;
        
if (!$dbtype) {
            
$rs = &$rs;  // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
            return $rs;
        }
下面这个判断也很清楚,当条件符合时执行(将指针移到第一位),返回对象。

        
if (($dbtype == 'array' || $dbtype == 'csv'&& $nrows == -1 && $offset == -1) {
            
$rs->MoveFirst();
            
$rs = &$rs// required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
            return $rs;
        }
下面的循环是返回每个要取出的数据库的字段名称及属性,存到$flds数组中,调用GetArrayLimit 函数。
        $flds = array();
        
for ($i=0, $max=$rs->FieldCount(); $i < $max$i++) {
            
$flds[] = $rs->FetchField($i);  //数据库字段名称及字段的属性
        }

        
$arr =& $rs->GetArrayLimit($nrows,$offset);
 
GetArrayLimit 函数:如果偏移量($offset)小于0 直接调用 GetArray函数返回数据数组,

        
if ($offset <= 0) {
            
$arr =& $this->GetArray($nrows);
            
return $arr;
        } 
否则移动指针到偏移量($offset)的位置,再循环移动指针取数据存储到数组,返回结果数组。
        $results = array();
        
$cnt = 0;
        
while (!$this->EOF && $nrows != $cnt) {
            
$results[$cnt++= $this->fields;
            
$this->MoveNext();
        }
 
返回 _rs2rs 函数:建立一个连接,设置连接属性,设置结果集字段属性, 返回对象。
        $rs2 =& new $arrayClass();
        
$rs2->connection = &$this;
        
$rs2->sql = $rs->sql;
        
$rs2->dataProvider = $this->dataProvider;
        
$rs2->InitArrayFields($arr,$flds);
        
$rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
        
return $rs2;
返回 SelectLimit函数:返回从_rs2rs 函数返回的结果。
返回 _adodb_pageexecute_all_rows函数:调用函数,设置分页信息,返回结果对象
返回 pageExecute函数:返回结果
到此,分页函数的取数据功能完成,接下来就是调用页面设置函数进行分页信息设置。
阅读更多
想对作者说点什么? 我来说一句

ADODB实现分页

一 代码

chengqiuming chengqiuming

2017-11-22 10:44:17

阅读数:22

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭