[转]某文本数据库blog作者写的文本数据库操作类,很不错

 

作者的1.0版:

/*
本代码开源,您可以对其进行修改.
下面文字请不要修改.
*********************************************
php文本数据库类1.0版
powerd by bpns
mysite:http://space.tju.cn/site/redboy/
2006-4-20
*********************************************

为了您的数据库安全,请在此程序中更改您的数据默认目录

将function TxtDB($name,$mod='w',$path='my_dbm')
中$path='my_dbm'修改成你自己设定的目录,如$path='abc123_dbm',
并将根目录下的my_dbm文件夹对行对应的更名.
*/

class 
TxtDB
{
  var 
$name='';
//文本数据库名
  
var $path=''
;
  var 
$minLen=20
;
  var 
$isError
;
  var 
$dbh
;
  var 
$indxh
;
  var 
$lfth
;
  var 
$lckh
;
  var 
$rcdCnt=0
;
  var 
$maxID=0
;
  var 
$leftCnt=0
;
  var 
$DBend=0
;
  var 
$mod='w'
;
  function 
TxtDB($name,$mod='w',$path='bpns_dbm')
//修改数据库的默认文件夹在此修改
  
{
    
$this->name=$name
;
    
$this->path=$path.'/'.$name
;
    
$this->isError=0
;
    
$this->mod=$mod
;
    
$path=$this->path
;
    if (
$name!=''
)
    {
    @
mkdir($this->path,0777
);
    if (!
file_exists($path.'/'.$name.'.tdb')) $this->dbh=fopen($this->path.'/'.$name.'.tdb','w+'
);
    else 
$this->dbh=fopen($path.'/'.$name.'.tdb','r+'
);
    if (!
file_exists($path.'/'.$name.'.indx')) $this->indxh=fopen($this->path.'/'.$name.'.indx','w+'
);
    else 
$this->indxh=fopen($path.'/'.$name.'.indx','r+'
);
    if (!
file_exists($path.'/'.$name.'.lft')) $this->lfth=fopen($this->path.'/'.$name.'.lft','w+'
);
    else 
$this->lfth=fopen($this->path.'/'.$name.'.lft','r+'
);
    if (
$this->mod=='w'
)
    {
     
$this->lckh=fopen($this->path.'/'.$name.'.lck','w'
);
     
flock($this->lckh,2
);
     
fwrite($this->lckh,'lck');
//lock the datebase
    
}
    
$rcd=$this->getRcd(0
);
    
$this->rcdCnt=$rcd[id
];
    
$this->maxID=$rcd[loc
];
    
$this->DBend=$rcd[len
];
    
$rcd=$this->getLeft(0
);
    
$this->leftCnt=$rcd[loc
];
    }
    else 
$this->isError=1
;
  }
  function 
setRcd($rid,$id,$loc,$len
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=pack('III',$id,$loc,$len
);
    
fwrite($this->indxh,$str,12
);
  }
  function 
getRcd($rid
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=fread($this->indxh,12
);
    
$rcd
=array();
    
$rcd[id]=str2int($str
);
    
$rcd[loc]=str2int(substr($str,4,4
));
    
$rcd[len]=str2int(substr($str,8,4
));
    return 
$rcd
;
  }
  function 
setLeft($lid,$loc,$len
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=pack('II',$loc,$len
);
    
fwrite($this->lfth,$str,8
);
  }
  function 
getLeft($lid
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=fread($this->lfth,8
);
    
$rcd[loc]=str2int($str
);
    
$rcd[len]=str2int(substr($str,4,4
));
    return 
$rcd
;
  }
  
  function 
clear
()
  {
    
$this->setRcd(0,0,0,0
);
    
$this->setLeft(0,0,0
);
  }
  function 
close
()
  {
    @
fclose($this->dbh
);
    @
fclose($this->indxh
);
    @
fclose($this->lfth
);
    @
fclose($this->lckh
);
  }
  
  function 
seekSpace($len
)
  {
    
$res=array('loc'=>0,'len'=>0
);
    if (
$this->leftCnt<1) return $res
;
    
$find=0
;
    
$min=1000000
;
    for (
$i=$this->leftCnt;$i>0;$i
--)
    {
      
$res=$this->getLeft($i
);
      if (
$res[len]==$len) {$find=$i
;break;}
      else if(
$res[len]>$len
)
      {
         if (
$res[len]-$len<$min
)
         {
           
$min=$res[len]-$len
;
           
$find=$i
;
         }
      }
    }
    if (
$find
)
    {
      
$res=$this->getLeft($find
);
      if (
$res[len]<2*$len
)
      {
       
fseek($this->lfth,($find+1)*8
);
       
$str=fread($this->lfth,($this->leftCnt-$find)*8
);
       
fseek($this->lfth,$find*8
);
       
fwrite($this->lfth,$str
);
       
$this->leftCnt
--;
       
$this->setLeft(0,$this->leftCnt,0
);
       return 
$res
;
      }
      else
      {
        
$rs
=array();
        
$rs[loc]=$res[loc
];
        
$rs[len]=$len
;
        
$res[loc]+=$len
;
        
$this->setLeft($find,$res[loc],$res[len]-$len
);
        return 
$rs
;
      }
    }
    else
//fail
    
{
      
$res[len]=0
;
      return 
$res
;
    }
  }
  function 
insert($content,$len=0)
//return with record id
  
{
    
$res=array('loc'=>0
);
    if (
$this->mod!='w') return 0
;
    if (!
$len$len=strlen($content
); 
    if (
$len<$this->minLen$len=$this->minLen
;
    if (
$this->leftCnt$res=$this->seekSpace($len
);
    if (!
$res[len
])
    {
      
$res[loc]=$this->DBend
;
      
$res[len]=$len
;
    }
    if (
$res[loc]+$res[len]>$this->DBend$this->DBend=$res[loc]+$res[len
];
    
//echo $this->DBend.'
';
    
$this->maxID
++;
    
$this->rcdCnt
++;
    
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    
$this->setRcd($this->rcdCnt,$this->maxID,$res[loc],$res[len
]);
    
fseek($this->dbh,$res[loc
]);
    
fwrite($this->dbh,$content,$len
);
    return 
$this->maxID
;
  }
  function 
findByID($id
)
  {
    if (
$id<or $id>$this->maxID or $this->rcdCnt<1) return 0
;
    
$left=1
;
    
$right=$this->rcdCnt
;
    while(
$left<$right
)
    {
      
$mid=(int)(($left+$right)/2
);
      if (
$mid==$left or $mid==$right
) break;
      
$rcd=$this->getRcd($mid
);
      if (
$rcd[id]==$id) return $mid
;
      else if(
$id<$rcd[id]) $right=$mid
;
      else 
$left=$mid
;
    }
    
//$rcd=$this->getRcd($mid);
    //if ($rcd[id]==$id) return $mid;
    
$rcd=$this->getRcd($left
);
    if (
$rcd[id]==$id) return $left
;
    
$rcd=$this->getRcd($right
);
    if (
$rcd[id]==$id) return $right
;
    return 
0
;
  }
  function 
delete($id
)
  {
    if (
$this->mod!='w') return 0
;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    
$res=$this->getRcd($rid
);
    
fseek($this->indxh,($rid+1)*12
);
    
$str=fread($this->indxh,($this->rcdCnt-$i)*12
);
    
fseek($this->indxh,$rid*12
);
    
fwrite($this->indxh,$str
);
    
$this->rcdCnt
--;
    if (
$res[loc]+$res[len]==$this->DBend
)
    {
      
$this->DBend=$res[loc
];
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    }
    else
    {
     
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
     
$this->leftCnt
++;
     
$this->setLeft(0,$this->leftCnt,0
);
     
$this->setLeft($this->leftCnt,$res[loc],$res[len
]);
    }
  }
  function 
update($id,$newcontent,$len=0
)
  {
    if (
$this->mod!='w'
) return;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    if (!
$len$len=strlen($newcontent
); 
    
$rcd=$this->getRcd($rid
);
    if (
$rcd[len]<$len
)
    {
      
$this->leftCnt
++;
      
$this->setLeft(0,$this->leftCnt,0
);
      
$this->setLeft($this->leftCnt,$rcd[loc],$rcd[len
]);
      
$rcd[loc]=$this->DBend
;
      
$rcd[len]=$len
;
      
$this->DBend+=$len
;
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
      
$this->setRcd($rid,$rcd[id],$rcd[loc],$rcd[len
]);
    }
    
fseek($this->dbh,$rcd[loc
]);
    
fwrite($this->dbh,$newcontent,$len
);
    
//echo $id.'
'.$content.'
'.$len;
  
}
  function 
selectByRid($rid
)
  {
    
$res=array('id'=>0,'content'=>''
);
    if (
$rid<or $rid>$this->rcdCnt) return $res
;
    else 
$rcd=$this->getRcd($rid
);
    
$res[id]=$rcd[id
];
    
$res[len]=$rcd[len
];
    
fseek($this->dbh,$rcd[loc
]);
    
$res[content]=fread($this->dbh,$rcd[len
]);
    return 
$res
;
  }
  function 
select($id
)
  {
    return 
$this->selectByRid($this->findByID($id
));
  }
  function 
backup
()
  {
    
copy($this->path.'/'.$this->name.'.tdb',$this->path.'/'.$this->name.'.tdb.bck'
);
    
copy($this->path.'/'.$this->name.'.indx',$this->path.'/'.$this->name.'.indx.bck'
);
    
copy($this->path.'/'.$this->name.'.lft',$this->path.'/'.$this->name.'.lft.bck'
);
  }
  function 
recover
()
  {
    
copy($this->path.'/'.$this->name.'.tdb.bck',$this->path.'/'.$this->name.'.tdb'
);
    
copy($this->path.'/'.$this->name.'.indx.bck',$this->path.'/'.$this->name.'.indx'
);
    
copy($this->path.'/'.$this->name.'.lft.bck',$this->path.'/'.$this->name.'.lft'
);
  }
}
?>

作者的2.0版,生成dbm:

class TxtDB
{
  var 
$name='';
//文本数据库名
  
var $path=''
;
  var 
$minLen=20
;
  var 
$isError
;
  var 
$dbh
;
  var 
$indxh
;
  var 
$lfth
;
  var 
$lckh
;
  var 
$rcdCnt=0
;
  var 
$maxID=0
;
  var 
$leftCnt=0
;
  var 
$DBend=0
;
  var 
$mod='w'
;
  function 
TxtDB($name,$mod='w',$path='bpns_dbm'
)
  {
    
$this->name=$name
;
    
$this->path=$path.'/'.$name
;
    
$this->isError=0
;
    
$this->mod=$mod
;
    
$path=$this->path
;
    if (
$name!=''
)
    {
    @
mkdir($this->path,0777
);
    if (!
file_exists($path.'/'.$name.'.tdb')) $this->dbh=fopen($this->path.'/'.$name.'.tdb','w+'
);
    else 
$this->dbh=fopen($path.'/'.$name.'.tdb','r+'
);
    if (!
file_exists($path.'/'.$name.'.indx')) $this->indxh=fopen($this->path.'/'.$name.'.indx','w+'
);
    else 
$this->indxh=fopen($path.'/'.$name.'.indx','r+'
);
    if (!
file_exists($path.'/'.$name.'.lft')) $this->lfth=fopen($this->path.'/'.$name.'.lft','w+'
);
    else 
$this->lfth=fopen($this->path.'/'.$name.'.lft','r+'
);
    if (
$this->mod=='w'
)
    {
     
$this->lckh=fopen($this->path.'/'.$name.'.lck','w'
);
     
flock($this->lckh,2
);
     
fwrite($this->lckh,'lck');
//lock the datebase
    
}
    
$rcd=$this->getRcd(0
);
    
$this->rcdCnt=$rcd[id
];
    
$this->maxID=$rcd[loc
];
    
$this->DBend=$rcd[len
];
    
$rcd=$this->getLeft(0
);
    
$this->leftCnt=$rcd[loc
];
    }
    else 
$this->isError=1
;
  }
  function 
setRcd($rid,$id,$loc,$len
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=pack('III',$id,$loc,$len
);
    
fwrite($this->indxh,$str,12
);
  }
  function 
getRcd($rid
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=fread($this->indxh,12
);
    
$rcd
=array();
    
$rcd[id]=str2int($str
);
    
$rcd[loc]=str2int(substr($str,4,4
));
    
$rcd[len]=str2int(substr($str,8,4
));
    return 
$rcd
;
  }
  function 
setLeft($lid,$loc,$len
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=pack('II',$loc,$len
);
    
fwrite($this->lfth,$str,8
);
  }
  function 
getLeft($lid
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=fread($this->lfth,8
);
    
$rcd[loc]=str2int($str
);
    
$rcd[len]=str2int(substr($str,4,4
));
    return 
$rcd
;
  }
  
  function 
clear
()
  {
    
$this->setRcd(0,0,0,0
);
    
$this->setLeft(0,0,0
);
  }
  function 
close
()
  {
    @
fclose($this->dbh
);
    @
fclose($this->indxh
);
    @
fclose($this->lfth
);
    @
fclose($this->lckh
);
  }
  
  function 
seekSpace($len
)
  {
    
$res=array('loc'=>0,'len'=>0
);
    if (
$this->leftCnt<1) return $res
;
    
$find=0
;
    
$min=1000000
;
    for (
$i=$this->leftCnt;$i>0;$i
--)
    {
      
$res=$this->getLeft($i
);
      if (
$res[len]==$len) {$find=$i
;break;}
      else if(
$res[len]>$len
)
      {
         if (
$res[len]-$len<$min
)
         {
           
$min=$res[len]-$len
;
           
$find=$i
;
         }
      }
    }
    if (
$find
)
    {
      
$res=$this->getLeft($find
);
      if (
$res[len]<2*$len
)
      {
       
fseek($this->lfth,($find+1)*8
);
       
$str=fread($this->lfth,($this->leftCnt-$find)*8
);
       
fseek($this->lfth,$find*8
);
       
fwrite($this->lfth,$str
);
       
$this->leftCnt
--;
       
$this->setLeft(0,$this->leftCnt,0
);
       return 
$res
;
      }
      else
      {
        
$rs
=array();
        
$rs[loc]=$res[loc
];
        
$rs[len]=$len
;
        
$res[loc]+=$len
;
        
$this->setLeft($find,$res[loc],$res[len]-$len
);
        return 
$rs
;
      }
    }
    else
//fail
    
{
      
$res[len]=0
;
      return 
$res
;
    }
  }
  function 
insert($content,$len=0)
//return with record id
  
{
    
$res=array('loc'=>0
);
    if (
$this->mod!='w') return 0
;
    if (!
$len$len=strlen($content
); 
    if (
$len<$this->minLen$len=$this->minLen
;
    if (
$this->leftCnt$res=$this->seekSpace($len
);
    if (!
$res[len
])
    {
      
$res[loc]=$this->DBend
;
      
$res[len]=$len
;
    }
    if (
$res[loc]+$res[len]>$this->DBend$this->DBend=$res[loc]+$res[len
];
    
//echo $this->DBend.'
';
    
$this->maxID
++;
    
$this->rcdCnt
++;
    
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    
$this->setRcd($this->rcdCnt,$this->maxID,$res[loc],$res[len
]);
    
fseek($this->dbh,$res[loc
]);
    
fwrite($this->dbh,$content,$len
);
    return 
$this->maxID
;
  }
  function 
findByID($id
)
  {
    if (
$id<or $id>$this->maxID or $this->rcdCnt<1) return 0
;
    
$left=1
;
    
$right=$this->rcdCnt
;
    while(
$left<$right
)
    {
      
$mid=(int)(($left+$right)/2
);
      if (
$mid==$left or $mid==$right
) break;
      
$rcd=$this->getRcd($mid
);
      if (
$rcd[id]==$id) return $mid
;
      else if(
$id<$rcd[id]) $right=$mid
;
      else 
$left=$mid
;
    }
    
//$rcd=$this->getRcd($mid);
    //if ($rcd[id]==$id) return $mid;
    
$rcd=$this->getRcd($left
);
    if (
$rcd[id]==$id) return $left
;
    
$rcd=$this->getRcd($right
);
    if (
$rcd[id]==$id) return $right
;
    return 
0
;
  }
  function 
delete($id
)
  {
    if (
$this->mod!='w') return 0
;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    
$res=$this->getRcd($rid
);
    
fseek($this->indxh,($rid+1)*12
);
    
$str=fread($this->indxh,($this->rcdCnt-$i)*12
);
    
fseek($this->indxh,$rid*12
);
    
fwrite($this->indxh,$str
);
    
$this->rcdCnt
--;
    if (
$res[loc]+$res[len]==$this->DBend
)
    {
      
$this->DBend=$res[loc
];
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    }
    else
    {
     
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
     
$this->leftCnt
++;
     
$this->setLeft(0,$this->leftCnt,0
);
     
$this->setLeft($this->leftCnt,$res[loc],$res[len
]);
    }
  }
  function 
update($id,$newcontent,$len=0
)
  {
    if (
$this->mod!='w'
) return;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    if (!
$len$len=strlen($newcontent
); 
    
$rcd=$this->getRcd($rid
);
    if (
$rcd[len]<$len
)
    {
      
$this->leftCnt
++;
      
$this->setLeft(0,$this->leftCnt,0
);
      
$this->setLeft($this->leftCnt,$rcd[loc],$rcd[len
]);
      
$rcd[loc]=$this->DBend
;
      
$rcd[len]=$len
;
      
$this->DBend+=$len
;
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
      
$this->setRcd($rid,$rcd[id],$rcd[loc],$rcd[len
]);
    }
    
fseek($this->dbh,$rcd[loc
]);
    
fwrite($this->dbh,$newcontent,$len
);
    
//echo $id.'
'.$content.'
'.$len;
  
}
  function 
selectByRid($rid
)
  {
    
$res=array('id'=>0,'content'=>''
);
    if (
$rid<or $rid>$this->rcdCnt) return $res
;
    else 
$rcd=$this->getRcd($rid
);
    
$res[id]=$rcd[id
];
    
$res[len]=$rcd[len
];
    
fseek($this->dbh,$rcd[loc
]);
    
$res[content]=fread($this->dbh,$rcd[len
]);
    
//$res[rid]=$rid;
    
return $res
;
  }
  function 
select($id
)
  {
    return 
$this->selectByRid($this->findByID($id
));
  }
  function 
backup
()
  {
    
copy($this->path.'/'.$this->name.'.tdb',$this->path.'/'.$this->name.'.tdb.bck'
);
    
copy($this->path.'/'.$this->name.'.indx',$this->path.'/'.$this->name.'.indx.bck'
);
    
copy($this->path.'/'.$this->name.'.lft',$this->path.'/'.$this->name.'.lft.bck'
);
  }
  function 
recover
()
  {
    
copy($this->path.'/'.$this->name.'.tdb.bck',$this->path.'/'.$this->name.'.tdb'
);
    
copy($this->path.'/'.$this->name.'.indx.bck',$this->path.'/'.$this->name.'.indx'
);
    
copy($this->path.'/'.$this->name.'.lft.bck',$this->path.'/'.$this->name.'.lft'
);
  }
}

?>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值