Andy's Blog » php txtdb pack » 奶瓶的文本数据库操作类

奶瓶的文本数据库操作类

未经测试,收藏一下

<?php
//=============================================================================//
//    程序名称:文本数据库操作类
//    程序作者:我是一只鱼(QQ:454813812)
//    写作时间:2005-03-12
//=============================================================================//
class TxtDb{
    
var $dataBase;
    
var $dataRows;
    
var $dataCache;
    
var $dataError;
    
function TxtDb($dataBase = "data"){
        
$this->dataBase  = $dataBase;
        
$this->dataCache = "cache";
        
$this->dataError = null;
    
}
    
function insert($tableName,$args){
        
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r+")){
            
$this->dataError = "数据表打开失败";
            
return false;
        
}else if(!strstr(fread($fp,20),"TDB")){
            
$this->dataError = "数据库文件被破坏或者格式错误";
            
fclose($fp);
            
return false;
        
}else{
            
fseek($fp,20,SEEK_CUR);
            
for($i=0,$result="1",$length=0,$tmp=explode(';',trim(fread($fp,160)));$i<count($tmp)-1;$i++){
                
list($key,$value) = explode(':',$tmp[$i]);
                
$length          += $value;
                
if(!array_key_exists($key,$args)){
                    
$result .= str_pad("",$value);
                
}else if(strlen($args[$key])>$value){
                    
$this->dataError = "用户字段太长 '$key' 错误";
                    
fclose($fp);
                    
return false;
                
}else{
                    
$result .= str_pad($args[$key],$value);
                
}
            
}
            
fseek($fp,0,SEEK_END);
            
fwrite($fp,$result);
            
fclose($fp);
            
return true;
        
}
    
}
    
function update($tableName,$rows,$args){
        
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r+")){
            
$this->dataError = "数据表打开失败";
            
return false;
        
}else if(!strstr(fread($fp,20),"TDB")){
            
$this->dataError = "数据库文件被破坏或者格式错误";
            
fclose($fp);
            
return false;
        
}else{
            
fseek($fp,20,SEEK_CUR);
            
for($i=0,$result="1",$length=0,$tmp=explode(';',trim(fread($fp,160)));$i<count($tmp)-1;$i++){
                
list($key,$value) = explode(':',$tmp[$i]);
                
$length          += $value;
                
if(!array_key_exists($key,$args)){
                    
$result .= str_pad("",$value);
                
}else if(strlen($args[$key])>$value){
                    
$this->dataError = "用户字段太长 '$key' 错误";
                    
fclose($fp);
                    
return false;
                
}else{
                    
$result .= str_pad($args[$key],$value);
                
}
            
}
            
if(fseek($fp,$rows*strlen($result)+200,SEEK_SET) == 0){
                
fwrite($fp,$result);
                
fclose($fp);
                
return true;
            
}else{
                
fclose($fp);
                
$this->dataError = "记录更新失败,数据定位失败";
                
return false;
            
}
        
}
    
}
    
function select($table,$rows){
        
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
            
$this->dataError = "数据表打开失败";
            
return false;
        
}else if(!strstr(fread($fp,20),"TDB")){
            
$this->dataError = "数据库文件被破坏或者格式错误";
            
fclose($fp);
            
return false;
        
}else{
            
fseek($fp,20,SEEK_CUR);
            
for($i=0,$result="1",$length=0,$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i<count($tmp)-1;$i++){
                
list($key,$value) = explode(':',$tmp[$i]);
                
$head[$key]       = $value;
                
$length          += $value;
            
}
            
if(fseek($fp,$rows*($length+1)+200,SEEK_SET) == 0){
                
$result = array('rows'=>$rows);
                
foreach($head AS $key=>$value)$result[$key] = fread($fp,$value);
                
fclose($fp);
                
return $result;
            
}else{
                
fclose($fp);
                
$this->dataError = "记录更新失败,数据定位失败";
                
return false;
            
}
        
}
    
}
    
function getAll($tableName,$query,$order = "0,desc",$limit = "0,100000"){
        
$cacheFile = $this->dataBase."/".$this->dataCache."/".md5("$tableName:$query:$order").".tdc";
        
list($order,$ordertype,$limit,$end) = explode(",",$order.','.$limit);
        
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
            
$this->dataError = "数据表打开失败";
            
return false;
        
}else if(!strstr(fread($fp,20),"TDB")){
            
$this->dataError = "数据库文件被破坏或者格式错误";
            
fclose($fp);
            
return false;
        
}else{
            
fseek($fp,20,SEEK_CUR);
            
for($i=0,$length=0,$result="1",$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i<count($tmp)-1;$i++){
                
list($key,$value) = explode(':',$tmp[$i]);
                
$head[$key]       = $value;
                
$length          += $value;
            
}
            
if(@filemtime($cacheFile) > time()-1000){
                
if($fp1 = fopen($cacheFile,"r")){
                    
$result = unpack("Vrows",fread($fp1,4));
                    
$this->dataRows = $result['rows'];
                    
if(fseek($fp1,($limit+1)*4,SEEK_SET) == 0){
                        
$result = unpack("V*",fread($fp1,$end*4));
                        
fclose($fp1);
                    
}else{
                        
fclose($fp);
                        
fclose($fp1);
                        
return false;
                    
}
                
}else{
                    
$this->dataError = "缓存文件打开错误";
                    
fclose($fp);
                    
fclose($fp1);
                    
return false;
                
}
            
}else if(fseek($fp,200,SEEK_SET) == 0){
                
$i = 0;
                
foreach($head AS $key=>$value){
                    
$query = str_replace("@$key","@".$i++,$query);
                
}
                
$result  = array();
                
preg_match_all('/@(\d+)/si',$query,$tmp);
                
$tmp[1][]= $order;
                
$query   = preg_replace('/@(\d+)/si','$row[\1]',$query);
                
$execute = '$i=0;while(true){if(strlen($type=fread($fp,1))!=1)break;$row=array(\'rows\'=>$i++);';
                
for($i=0,$id=empty($tmp[1])?100:max($tmp[1]),$sum=0,$values=array_values($head);$i<count($head);$i++){
                    
$sum     += $values[$i];
                    
$execute .= '$row[]=trim(fread($fp,'.$values[$i].'));';
                    
if($id <= $i){
                        
$execute .= 'fseek($fp,'.($length-$sum).',SEEK_CUR);';
                        
break;
                    
}
                
}
                
eval($execute.'if($type==\'1\' && '.$query.'){$result[] = array($i-1,$row[$order]);}}');
                
usort($result,
                        
create_function('$a,$b',$ordertype=="desc"?'return strcmp($a[1],$b[1]);':'return strcmp($b[1],$a[1]);'));
                
for($i=0,$tmp='';$i<count($result);$i++){$tmp .= pack("V",$result[$i][0]);}
                
if($fp1 = fopen($cacheFile,"w")){
                    
fwrite($fp1,pack("V",($this->dataRows = strlen($tmp)/4)).$tmp);
                    
fclose($fp1);
                
}
                
$result       = unpack("V*",substr($tmp,$limit*4,$end*4));
            
}else{
                
fclose($fp);
                
$this->dataError = "记录查询失败,数据定位失败";
                
return false;
            
}
            
$tmp = $row = array();
            
foreach($result as $rows){
                
fseek($fp,$rows*($length+1)+201,SEEK_SET);
                
foreach($head AS $key=>$value){
                    
$row[$key] = trim(fread($fp,$value));
                
}
                
$tmp[] = $row;
            
}
            
fclose($fp);
            
return $tmp;
        
}
    
}
    
function remove($tableName,$query){
        
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
            
$this->dataError = "数据表打开失败";
            
return false;
        
}else if(!strstr(fread($fp,20),"TDB")){
            
$this->dataError = "数据库文件被破坏或者格式错误";
            
fclose($fp);
            
return false;
        
}else{
            
fseek($fp,20,SEEK_CUR);
            
for($i=0,$length=0,$result="1",$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i<count($tmp)-1;$i++){
                
list($key,$value) = explode(':',$tmp[$i]);
                
$head[$key]       = $value;
                
$length          += $value;
            
}
            
$i = 0;
            
foreach($head AS $key=>$value){
                
$query = str_replace("@$key","@".$i++,$query);
            
}
            
$result  = array();
            
preg_match_all('/@(\d+)/si',$query,$tmp);
            
$tmp[1][]= $order;
            
$query   = preg_replace('/@(\d+)/si','$row[\1]',$query);
            
$execute = '$i=0;while(true){if(strlen($type=fread($fp,1))!=1)break;$row=array(\'rows\'=>$i++);';
            
for($i=$rows=0,$id=empty($tmp[1])?100:max($tmp[1]),$sum=0,$values=array_values($head);$i<count($head);$i++){
                
$sum     += $values[$i];
                
$execute .= '$row[]=trim(fread($fp,'.$values[$i].'));';
                
if($id <= $i){
                    
$execute .= 'fseek($fp,'.($length-$sum).',SEEK_CUR);';
                    
break;
                
}
            
}
            
$execute .= 'if($type==\'1\' && '.$query.'){fseek($fp,'.(-1*($length+1)).',SEEK_CUR);';
            
eval($execute.'fwrite($fp,\'0\');$rows++;seek($fp,'.$length.',SEEK_CUR);}}');
            
if($dp = dir($this->dataBase."/".$this->dataCache)){
                
while($file = $db->read())if(strstr($file,"tdc"))unlink($this->dataBase."/".$this->dataCache."/$file");
                
$dp->close();
            
}
            
fclose($fp);
            
return $rows;
        
}
    
}
    
function clean($tableName){
        
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
            
$this->dataError = "数据表打开失败";
            
return false;
        
}else if(!strstr(fread($fp,20),"TDB")){
            
$this->dataError = "数据库文件被破坏或者格式错误";
            
fclose($fp);
            
return false;
        
}else{
            
fseek($fp,20,SEEK_CUR);
            
for($i=0,$length=0,$result="1",$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i<count($tmp)-1;$i++){
                
list($key,$value) = explode(':',$tmp[$i]);
                
$head[$key]       = $value;
                
$length          += $value;
            
}
            
if(rewind($this->fp) && $fp1 = fopen($this->dataBase."/".$tableName.".tdb.tmp","w")){
                
fwrite($fp1,fread($fp,200));
                
while(strlen($tmp = fread($fp,$length+1))){
                    
($tmp{0} == "1") && fwrite($fp1,$tmp);
                
}
                
fclose($fp1);
                
fclose($fp);
                
unlink($this->dataBase."/".$tableName.".tdb");
                
rename($this->dataBase."/".$tableName.".tdb.tmp",$this->dataBase."/".$tableName.".tdb");
                
if($dp = dir($this->dataBase."/".$this->dataCache)){
                
while($file = $db->read())if(strstr($file,"tdc"))unlink($this->dataBase."/".$this->dataCache."/$file");
                    
$dp->close();
                
}
                
return true;
            
}else{
                
fclose($fp);
                
return false;
            
}
        
}
    
}
    
function create($tableName,$args){
        
if(file_exists($this->dataBase."/".$tableName.".tdb")){
            
$this->dataError = "数据表 $table 已经存在";
        
}else if($fp = fopen($this->dataBase."/".$tableName.".tdb","w")){
            
fwrite($fp,str_pad("TDB1.0",20));
            
fwrite($fp,pack("V*",0,0,0,count($args),array_sum($args)));
            
$tmp = "";
            
foreach($args AS $key=>$value)$tmp .= "$key:$value;";
            
fwrite($fp,str_pad($tmp,160));
            
fclose($fp);
            
return true;
        
}else{
            
$this->dataError = "数据表建立失败";
            
return false;
        
}
    
}
}
?>

Incoming search terms:

Tags: PHP, class,

本文地址: http://www.21andy.com/new/20060622/353.html

1 评论 to “PHP开源CMS之MODx”

  1. 格式 于 2006-06-22 14:09:24 发表:

    格式超宽了